uboot/arch/powerpc/cpu/mpc8xxx/ddr/options.c
<<
>>
Prefs
   1/*
   2 * Copyright 2008, 2010-2012 Freescale Semiconductor, Inc.
   3 *
   4 * This program is free software; you can redistribute it and/or modify it
   5 * under the terms of the GNU General Public License as published by the Free
   6 * Software Foundation; either version 2 of the License, or (at your option)
   7 * any later version.
   8 */
   9
  10#include <common.h>
  11#include <hwconfig.h>
  12#include <asm/fsl_ddr_sdram.h>
  13
  14#include "ddr.h"
  15
  16/*
  17 * Use our own stack based buffer before relocation to allow accessing longer
  18 * hwconfig strings that might be in the environment before we've relocated.
  19 * This is pretty fragile on both the use of stack and if the buffer is big
  20 * enough. However we will get a warning from getenv_f for the later.
  21 */
  22
  23/* Board-specific functions defined in each board's ddr.c */
  24extern void fsl_ddr_board_options(memctl_options_t *popts,
  25                dimm_params_t *pdimm,
  26                unsigned int ctrl_num);
  27
  28struct dynamic_odt {
  29        unsigned int odt_rd_cfg;
  30        unsigned int odt_wr_cfg;
  31        unsigned int odt_rtt_norm;
  32        unsigned int odt_rtt_wr;
  33};
  34
  35#ifdef CONFIG_FSL_DDR3
  36static const struct dynamic_odt single_Q[4] = {
  37        {       /* cs0 */
  38                FSL_DDR_ODT_NEVER,
  39                FSL_DDR_ODT_CS_AND_OTHER_DIMM,
  40                DDR3_RTT_20_OHM,
  41                DDR3_RTT_120_OHM
  42        },
  43        {       /* cs1 */
  44                FSL_DDR_ODT_NEVER,
  45                FSL_DDR_ODT_NEVER,      /* tied high */
  46                DDR3_RTT_OFF,
  47                DDR3_RTT_120_OHM
  48        },
  49        {       /* cs2 */
  50                FSL_DDR_ODT_NEVER,
  51                FSL_DDR_ODT_CS_AND_OTHER_DIMM,
  52                DDR3_RTT_20_OHM,
  53                DDR3_RTT_120_OHM
  54        },
  55        {       /* cs3 */
  56                FSL_DDR_ODT_NEVER,
  57                FSL_DDR_ODT_NEVER,      /* tied high */
  58                DDR3_RTT_OFF,
  59                DDR3_RTT_120_OHM
  60        }
  61};
  62
  63static const struct dynamic_odt single_D[4] = {
  64        {       /* cs0 */
  65                FSL_DDR_ODT_NEVER,
  66                FSL_DDR_ODT_ALL,
  67                DDR3_RTT_40_OHM,
  68                DDR3_RTT_OFF
  69        },
  70        {       /* cs1 */
  71                FSL_DDR_ODT_NEVER,
  72                FSL_DDR_ODT_NEVER,
  73                DDR3_RTT_OFF,
  74                DDR3_RTT_OFF
  75        },
  76        {0, 0, 0, 0},
  77        {0, 0, 0, 0}
  78};
  79
  80static const struct dynamic_odt single_S[4] = {
  81        {       /* cs0 */
  82                FSL_DDR_ODT_NEVER,
  83                FSL_DDR_ODT_ALL,
  84                DDR3_RTT_40_OHM,
  85                DDR3_RTT_OFF
  86        },
  87        {0, 0, 0, 0},
  88        {0, 0, 0, 0},
  89        {0, 0, 0, 0},
  90};
  91
  92static const struct dynamic_odt dual_DD[4] = {
  93        {       /* cs0 */
  94                FSL_DDR_ODT_NEVER,
  95                FSL_DDR_ODT_SAME_DIMM,
  96                DDR3_RTT_120_OHM,
  97                DDR3_RTT_OFF
  98        },
  99        {       /* cs1 */
 100                FSL_DDR_ODT_OTHER_DIMM,
 101                FSL_DDR_ODT_OTHER_DIMM,
 102                DDR3_RTT_30_OHM,
 103                DDR3_RTT_OFF
 104        },
 105        {       /* cs2 */
 106                FSL_DDR_ODT_NEVER,
 107                FSL_DDR_ODT_SAME_DIMM,
 108                DDR3_RTT_120_OHM,
 109                DDR3_RTT_OFF
 110        },
 111        {       /* cs3 */
 112                FSL_DDR_ODT_OTHER_DIMM,
 113                FSL_DDR_ODT_OTHER_DIMM,
 114                DDR3_RTT_30_OHM,
 115                DDR3_RTT_OFF
 116        }
 117};
 118
 119static const struct dynamic_odt dual_DS[4] = {
 120        {       /* cs0 */
 121                FSL_DDR_ODT_NEVER,
 122                FSL_DDR_ODT_SAME_DIMM,
 123                DDR3_RTT_120_OHM,
 124                DDR3_RTT_OFF
 125        },
 126        {       /* cs1 */
 127                FSL_DDR_ODT_OTHER_DIMM,
 128                FSL_DDR_ODT_OTHER_DIMM,
 129                DDR3_RTT_30_OHM,
 130                DDR3_RTT_OFF
 131        },
 132        {       /* cs2 */
 133                FSL_DDR_ODT_OTHER_DIMM,
 134                FSL_DDR_ODT_ALL,
 135                DDR3_RTT_20_OHM,
 136                DDR3_RTT_120_OHM
 137        },
 138        {0, 0, 0, 0}
 139};
 140static const struct dynamic_odt dual_SD[4] = {
 141        {       /* cs0 */
 142                FSL_DDR_ODT_OTHER_DIMM,
 143                FSL_DDR_ODT_ALL,
 144                DDR3_RTT_20_OHM,
 145                DDR3_RTT_120_OHM
 146        },
 147        {0, 0, 0, 0},
 148        {       /* cs2 */
 149                FSL_DDR_ODT_NEVER,
 150                FSL_DDR_ODT_SAME_DIMM,
 151                DDR3_RTT_120_OHM,
 152                DDR3_RTT_OFF
 153        },
 154        {       /* cs3 */
 155                FSL_DDR_ODT_OTHER_DIMM,
 156                FSL_DDR_ODT_OTHER_DIMM,
 157                DDR3_RTT_20_OHM,
 158                DDR3_RTT_OFF
 159        }
 160};
 161
 162static const struct dynamic_odt dual_SS[4] = {
 163        {       /* cs0 */
 164                FSL_DDR_ODT_OTHER_DIMM,
 165                FSL_DDR_ODT_ALL,
 166                DDR3_RTT_30_OHM,
 167                DDR3_RTT_120_OHM
 168        },
 169        {0, 0, 0, 0},
 170        {       /* cs2 */
 171                FSL_DDR_ODT_OTHER_DIMM,
 172                FSL_DDR_ODT_ALL,
 173                DDR3_RTT_30_OHM,
 174                DDR3_RTT_120_OHM
 175        },
 176        {0, 0, 0, 0}
 177};
 178
 179static const struct dynamic_odt dual_D0[4] = {
 180        {       /* cs0 */
 181                FSL_DDR_ODT_NEVER,
 182                FSL_DDR_ODT_SAME_DIMM,
 183                DDR3_RTT_40_OHM,
 184                DDR3_RTT_OFF
 185        },
 186        {       /* cs1 */
 187                FSL_DDR_ODT_NEVER,
 188                FSL_DDR_ODT_NEVER,
 189                DDR3_RTT_OFF,
 190                DDR3_RTT_OFF
 191        },
 192        {0, 0, 0, 0},
 193        {0, 0, 0, 0}
 194};
 195
 196static const struct dynamic_odt dual_0D[4] = {
 197        {0, 0, 0, 0},
 198        {0, 0, 0, 0},
 199        {       /* cs2 */
 200                FSL_DDR_ODT_NEVER,
 201                FSL_DDR_ODT_SAME_DIMM,
 202                DDR3_RTT_40_OHM,
 203                DDR3_RTT_OFF
 204        },
 205        {       /* cs3 */
 206                FSL_DDR_ODT_NEVER,
 207                FSL_DDR_ODT_NEVER,
 208                DDR3_RTT_OFF,
 209                DDR3_RTT_OFF
 210        }
 211};
 212
 213static const struct dynamic_odt dual_S0[4] = {
 214        {       /* cs0 */
 215                FSL_DDR_ODT_NEVER,
 216                FSL_DDR_ODT_CS,
 217                DDR3_RTT_40_OHM,
 218                DDR3_RTT_OFF
 219        },
 220        {0, 0, 0, 0},
 221        {0, 0, 0, 0},
 222        {0, 0, 0, 0}
 223
 224};
 225
 226static const struct dynamic_odt dual_0S[4] = {
 227        {0, 0, 0, 0},
 228        {0, 0, 0, 0},
 229        {       /* cs2 */
 230                FSL_DDR_ODT_NEVER,
 231                FSL_DDR_ODT_CS,
 232                DDR3_RTT_40_OHM,
 233                DDR3_RTT_OFF
 234        },
 235        {0, 0, 0, 0}
 236
 237};
 238
 239static const struct dynamic_odt odt_unknown[4] = {
 240        {       /* cs0 */
 241                FSL_DDR_ODT_NEVER,
 242                FSL_DDR_ODT_CS,
 243                DDR3_RTT_120_OHM,
 244                DDR3_RTT_OFF
 245        },
 246        {       /* cs1 */
 247                FSL_DDR_ODT_NEVER,
 248                FSL_DDR_ODT_CS,
 249                DDR3_RTT_120_OHM,
 250                DDR3_RTT_OFF
 251        },
 252        {       /* cs2 */
 253                FSL_DDR_ODT_NEVER,
 254                FSL_DDR_ODT_CS,
 255                DDR3_RTT_120_OHM,
 256                DDR3_RTT_OFF
 257        },
 258        {       /* cs3 */
 259                FSL_DDR_ODT_NEVER,
 260                FSL_DDR_ODT_CS,
 261                DDR3_RTT_120_OHM,
 262                DDR3_RTT_OFF
 263        }
 264};
 265#else   /* CONFIG_FSL_DDR3 */
 266static const struct dynamic_odt single_Q[4] = {
 267        {0, 0, 0, 0},
 268        {0, 0, 0, 0},
 269        {0, 0, 0, 0},
 270        {0, 0, 0, 0}
 271};
 272
 273static const struct dynamic_odt single_D[4] = {
 274        {       /* cs0 */
 275                FSL_DDR_ODT_NEVER,
 276                FSL_DDR_ODT_ALL,
 277                DDR2_RTT_150_OHM,
 278                DDR2_RTT_OFF
 279        },
 280        {       /* cs1 */
 281                FSL_DDR_ODT_NEVER,
 282                FSL_DDR_ODT_NEVER,
 283                DDR2_RTT_OFF,
 284                DDR2_RTT_OFF
 285        },
 286        {0, 0, 0, 0},
 287        {0, 0, 0, 0}
 288};
 289
 290static const struct dynamic_odt single_S[4] = {
 291        {       /* cs0 */
 292                FSL_DDR_ODT_NEVER,
 293                FSL_DDR_ODT_ALL,
 294                DDR2_RTT_150_OHM,
 295                DDR2_RTT_OFF
 296        },
 297        {0, 0, 0, 0},
 298        {0, 0, 0, 0},
 299        {0, 0, 0, 0},
 300};
 301
 302static const struct dynamic_odt dual_DD[4] = {
 303        {       /* cs0 */
 304                FSL_DDR_ODT_OTHER_DIMM,
 305                FSL_DDR_ODT_OTHER_DIMM,
 306                DDR2_RTT_75_OHM,
 307                DDR2_RTT_OFF
 308        },
 309        {       /* cs1 */
 310                FSL_DDR_ODT_NEVER,
 311                FSL_DDR_ODT_NEVER,
 312                DDR2_RTT_OFF,
 313                DDR2_RTT_OFF
 314        },
 315        {       /* cs2 */
 316                FSL_DDR_ODT_OTHER_DIMM,
 317                FSL_DDR_ODT_OTHER_DIMM,
 318                DDR2_RTT_75_OHM,
 319                DDR2_RTT_OFF
 320        },
 321        {       /* cs3 */
 322                FSL_DDR_ODT_NEVER,
 323                FSL_DDR_ODT_NEVER,
 324                DDR2_RTT_OFF,
 325                DDR2_RTT_OFF
 326        }
 327};
 328
 329static const struct dynamic_odt dual_DS[4] = {
 330        {       /* cs0 */
 331                FSL_DDR_ODT_OTHER_DIMM,
 332                FSL_DDR_ODT_OTHER_DIMM,
 333                DDR2_RTT_75_OHM,
 334                DDR2_RTT_OFF
 335        },
 336        {       /* cs1 */
 337                FSL_DDR_ODT_NEVER,
 338                FSL_DDR_ODT_NEVER,
 339                DDR2_RTT_OFF,
 340                DDR2_RTT_OFF
 341        },
 342        {       /* cs2 */
 343                FSL_DDR_ODT_OTHER_DIMM,
 344                FSL_DDR_ODT_OTHER_DIMM,
 345                DDR2_RTT_75_OHM,
 346                DDR2_RTT_OFF
 347        },
 348        {0, 0, 0, 0}
 349};
 350
 351static const struct dynamic_odt dual_SD[4] = {
 352        {       /* cs0 */
 353                FSL_DDR_ODT_OTHER_DIMM,
 354                FSL_DDR_ODT_OTHER_DIMM,
 355                DDR2_RTT_75_OHM,
 356                DDR2_RTT_OFF
 357        },
 358        {0, 0, 0, 0},
 359        {       /* cs2 */
 360                FSL_DDR_ODT_OTHER_DIMM,
 361                FSL_DDR_ODT_OTHER_DIMM,
 362                DDR2_RTT_75_OHM,
 363                DDR2_RTT_OFF
 364        },
 365        {       /* cs3 */
 366                FSL_DDR_ODT_NEVER,
 367                FSL_DDR_ODT_NEVER,
 368                DDR2_RTT_OFF,
 369                DDR2_RTT_OFF
 370        }
 371};
 372
 373static const struct dynamic_odt dual_SS[4] = {
 374        {       /* cs0 */
 375                FSL_DDR_ODT_OTHER_DIMM,
 376                FSL_DDR_ODT_OTHER_DIMM,
 377                DDR2_RTT_75_OHM,
 378                DDR2_RTT_OFF
 379        },
 380        {0, 0, 0, 0},
 381        {       /* cs2 */
 382                FSL_DDR_ODT_OTHER_DIMM,
 383                FSL_DDR_ODT_OTHER_DIMM,
 384                DDR2_RTT_75_OHM,
 385                DDR2_RTT_OFF
 386        },
 387        {0, 0, 0, 0}
 388};
 389
 390static const struct dynamic_odt dual_D0[4] = {
 391        {       /* cs0 */
 392                FSL_DDR_ODT_NEVER,
 393                FSL_DDR_ODT_ALL,
 394                DDR2_RTT_150_OHM,
 395                DDR2_RTT_OFF
 396        },
 397        {       /* cs1 */
 398                FSL_DDR_ODT_NEVER,
 399                FSL_DDR_ODT_NEVER,
 400                DDR2_RTT_OFF,
 401                DDR2_RTT_OFF
 402        },
 403        {0, 0, 0, 0},
 404        {0, 0, 0, 0}
 405};
 406
 407static const struct dynamic_odt dual_0D[4] = {
 408        {0, 0, 0, 0},
 409        {0, 0, 0, 0},
 410        {       /* cs2 */
 411                FSL_DDR_ODT_NEVER,
 412                FSL_DDR_ODT_ALL,
 413                DDR2_RTT_150_OHM,
 414                DDR2_RTT_OFF
 415        },
 416        {       /* cs3 */
 417                FSL_DDR_ODT_NEVER,
 418                FSL_DDR_ODT_NEVER,
 419                DDR2_RTT_OFF,
 420                DDR2_RTT_OFF
 421        }
 422};
 423
 424static const struct dynamic_odt dual_S0[4] = {
 425        {       /* cs0 */
 426                FSL_DDR_ODT_NEVER,
 427                FSL_DDR_ODT_CS,
 428                DDR2_RTT_150_OHM,
 429                DDR2_RTT_OFF
 430        },
 431        {0, 0, 0, 0},
 432        {0, 0, 0, 0},
 433        {0, 0, 0, 0}
 434
 435};
 436
 437static const struct dynamic_odt dual_0S[4] = {
 438        {0, 0, 0, 0},
 439        {0, 0, 0, 0},
 440        {       /* cs2 */
 441                FSL_DDR_ODT_NEVER,
 442                FSL_DDR_ODT_CS,
 443                DDR2_RTT_150_OHM,
 444                DDR2_RTT_OFF
 445        },
 446        {0, 0, 0, 0}
 447
 448};
 449
 450static const struct dynamic_odt odt_unknown[4] = {
 451        {       /* cs0 */
 452                FSL_DDR_ODT_NEVER,
 453                FSL_DDR_ODT_CS,
 454                DDR2_RTT_75_OHM,
 455                DDR2_RTT_OFF
 456        },
 457        {       /* cs1 */
 458                FSL_DDR_ODT_NEVER,
 459                FSL_DDR_ODT_NEVER,
 460                DDR2_RTT_OFF,
 461                DDR2_RTT_OFF
 462        },
 463        {       /* cs2 */
 464                FSL_DDR_ODT_NEVER,
 465                FSL_DDR_ODT_CS,
 466                DDR2_RTT_75_OHM,
 467                DDR2_RTT_OFF
 468        },
 469        {       /* cs3 */
 470                FSL_DDR_ODT_NEVER,
 471                FSL_DDR_ODT_NEVER,
 472                DDR2_RTT_OFF,
 473                DDR2_RTT_OFF
 474        }
 475};
 476#endif
 477
 478/*
 479 * Automatically seleect bank interleaving mode based on DIMMs
 480 * in this order: cs0_cs1_cs2_cs3, cs0_cs1, null.
 481 * This function only deal with one or two slots per controller.
 482 */
 483static inline unsigned int auto_bank_intlv(dimm_params_t *pdimm)
 484{
 485#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
 486        if (pdimm[0].n_ranks == 4)
 487                return FSL_DDR_CS0_CS1_CS2_CS3;
 488        else if (pdimm[0].n_ranks == 2)
 489                return FSL_DDR_CS0_CS1;
 490#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
 491#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
 492        if (pdimm[0].n_ranks == 4)
 493                return FSL_DDR_CS0_CS1_CS2_CS3;
 494#endif
 495        if (pdimm[0].n_ranks == 2) {
 496                if (pdimm[1].n_ranks == 2)
 497                        return FSL_DDR_CS0_CS1_CS2_CS3;
 498                else
 499                        return FSL_DDR_CS0_CS1;
 500        }
 501#endif
 502        return 0;
 503}
 504
 505unsigned int populate_memctl_options(int all_DIMMs_registered,
 506                        memctl_options_t *popts,
 507                        dimm_params_t *pdimm,
 508                        unsigned int ctrl_num)
 509{
 510        unsigned int i;
 511        char buffer[HWCONFIG_BUFFER_SIZE];
 512        char *buf = NULL;
 513#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2)
 514        const struct dynamic_odt *pdodt = odt_unknown;
 515#endif
 516        ulong ddr_freq;
 517
 518        /*
 519         * Extract hwconfig from environment since we have not properly setup
 520         * the environment but need it for ddr config params
 521         */
 522        if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
 523                buf = buffer;
 524
 525#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2)
 526        /* Chip select options. */
 527        if (CONFIG_DIMM_SLOTS_PER_CTLR == 1) {
 528                switch (pdimm[0].n_ranks) {
 529                case 1:
 530                        pdodt = single_S;
 531                        break;
 532                case 2:
 533                        pdodt = single_D;
 534                        break;
 535                case 4:
 536                        pdodt = single_Q;
 537                        break;
 538                }
 539        } else if (CONFIG_DIMM_SLOTS_PER_CTLR == 2) {
 540                switch (pdimm[0].n_ranks) {
 541#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
 542                case 4:
 543                        pdodt = single_Q;
 544                        if (pdimm[1].n_ranks)
 545                                printf("Error: Quad- and Dual-rank DIMMs "
 546                                        "cannot be used together\n");
 547                        break;
 548#endif
 549                case 2:
 550                        switch (pdimm[1].n_ranks) {
 551                        case 2:
 552                                pdodt = dual_DD;
 553                                break;
 554                        case 1:
 555                                pdodt = dual_DS;
 556                                break;
 557                        case 0:
 558                                pdodt = dual_D0;
 559                                break;
 560                        }
 561                        break;
 562                case 1:
 563                        switch (pdimm[1].n_ranks) {
 564                        case 2:
 565                                pdodt = dual_SD;
 566                                break;
 567                        case 1:
 568                                pdodt = dual_SS;
 569                                break;
 570                        case 0:
 571                                pdodt = dual_S0;
 572                                break;
 573                        }
 574                        break;
 575                case 0:
 576                        switch (pdimm[1].n_ranks) {
 577                        case 2:
 578                                pdodt = dual_0D;
 579                                break;
 580                        case 1:
 581                                pdodt = dual_0S;
 582                                break;
 583                        }
 584                        break;
 585                }
 586        }
 587#endif
 588
 589        /* Pick chip-select local options. */
 590        for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
 591#if defined(CONFIG_FSL_DDR3) || defined(CONFIG_FSL_DDR2)
 592                popts->cs_local_opts[i].odt_rd_cfg = pdodt[i].odt_rd_cfg;
 593                popts->cs_local_opts[i].odt_wr_cfg = pdodt[i].odt_wr_cfg;
 594                popts->cs_local_opts[i].odt_rtt_norm = pdodt[i].odt_rtt_norm;
 595                popts->cs_local_opts[i].odt_rtt_wr = pdodt[i].odt_rtt_wr;
 596#else
 597                popts->cs_local_opts[i].odt_rd_cfg = FSL_DDR_ODT_NEVER;
 598                popts->cs_local_opts[i].odt_wr_cfg = FSL_DDR_ODT_CS;
 599#endif
 600                popts->cs_local_opts[i].auto_precharge = 0;
 601        }
 602
 603        /* Pick interleaving mode. */
 604
 605        /*
 606         * 0 = no interleaving
 607         * 1 = interleaving between 2 controllers
 608         */
 609        popts->memctl_interleaving = 0;
 610
 611        /*
 612         * 0 = cacheline
 613         * 1 = page
 614         * 2 = (logical) bank
 615         * 3 = superbank (only if CS interleaving is enabled)
 616         */
 617        popts->memctl_interleaving_mode = 0;
 618
 619        /*
 620         * 0: cacheline: bit 30 of the 36-bit physical addr selects the memctl
 621         * 1: page:      bit to the left of the column bits selects the memctl
 622         * 2: bank:      bit to the left of the bank bits selects the memctl
 623         * 3: superbank: bit to the left of the chip select selects the memctl
 624         *
 625         * NOTE: ba_intlv (rank interleaving) is independent of memory
 626         * controller interleaving; it is only within a memory controller.
 627         * Must use superbank interleaving if rank interleaving is used and
 628         * memory controller interleaving is enabled.
 629         */
 630
 631        /*
 632         * 0 = no
 633         * 0x40 = CS0,CS1
 634         * 0x20 = CS2,CS3
 635         * 0x60 = CS0,CS1 + CS2,CS3
 636         * 0x04 = CS0,CS1,CS2,CS3
 637         */
 638        popts->ba_intlv_ctl = 0;
 639
 640        /* Memory Organization Parameters */
 641        popts->registered_dimm_en = all_DIMMs_registered;
 642
 643        /* Operational Mode Paramters */
 644
 645        /* Pick ECC modes */
 646        popts->ECC_mode = 0;              /* 0 = disabled, 1 = enabled */
 647#ifdef CONFIG_DDR_ECC
 648        if (hwconfig_sub_f("fsl_ddr", "ecc", buf)) {
 649                if (hwconfig_subarg_cmp_f("fsl_ddr", "ecc", "on", buf))
 650                        popts->ECC_mode = 1;
 651        } else
 652                popts->ECC_mode = 1;
 653#endif
 654        popts->ECC_init_using_memctl = 1; /* 0 = use DMA, 1 = use memctl */
 655
 656        /*
 657         * Choose DQS config
 658         * 0 for DDR1
 659         * 1 for DDR2
 660         */
 661#if defined(CONFIG_FSL_DDR1)
 662        popts->DQS_config = 0;
 663#elif defined(CONFIG_FSL_DDR2) || defined(CONFIG_FSL_DDR3)
 664        popts->DQS_config = 1;
 665#endif
 666
 667        /* Choose self-refresh during sleep. */
 668        popts->self_refresh_in_sleep = 1;
 669
 670        /* Choose dynamic power management mode. */
 671        popts->dynamic_power = 0;
 672
 673        /*
 674         * check first dimm for primary sdram width
 675         * presuming all dimms are similar
 676         * 0 = 64-bit, 1 = 32-bit, 2 = 16-bit
 677         */
 678#if defined(CONFIG_FSL_DDR1) || defined(CONFIG_FSL_DDR2)
 679        if (pdimm[0].n_ranks != 0) {
 680                if ((pdimm[0].data_width >= 64) && \
 681                        (pdimm[0].data_width <= 72))
 682                        popts->data_bus_width = 0;
 683                else if ((pdimm[0].data_width >= 32) || \
 684                        (pdimm[0].data_width <= 40))
 685                        popts->data_bus_width = 1;
 686                else {
 687                        panic("Error: data width %u is invalid!\n",
 688                                pdimm[0].data_width);
 689                }
 690        }
 691#else
 692        if (pdimm[0].n_ranks != 0) {
 693                if (pdimm[0].primary_sdram_width == 64)
 694                        popts->data_bus_width = 0;
 695                else if (pdimm[0].primary_sdram_width == 32)
 696                        popts->data_bus_width = 1;
 697                else if (pdimm[0].primary_sdram_width == 16)
 698                        popts->data_bus_width = 2;
 699                else {
 700                        panic("Error: primary sdram width %u is invalid!\n",
 701                                pdimm[0].primary_sdram_width);
 702                }
 703        }
 704#endif
 705
 706        /* Choose burst length. */
 707#if defined(CONFIG_FSL_DDR3)
 708#if defined(CONFIG_E500MC)
 709        popts->OTF_burst_chop_en = 0;   /* on-the-fly burst chop disable */
 710        popts->burst_length = DDR_BL8;  /* Fixed 8-beat burst len */
 711#else
 712        if ((popts->data_bus_width == 1) || (popts->data_bus_width == 2)) {
 713                /* 32-bit or 16-bit bus */
 714                popts->OTF_burst_chop_en = 0;
 715                popts->burst_length = DDR_BL8;
 716        } else {
 717                popts->OTF_burst_chop_en = 1;   /* on-the-fly burst chop */
 718                popts->burst_length = DDR_OTF;  /* on-the-fly BC4 and BL8 */
 719        }
 720#endif
 721#else
 722        popts->burst_length = DDR_BL4;  /* has to be 4 for DDR2 */
 723#endif
 724
 725        /* Choose ddr controller address mirror mode */
 726#if defined(CONFIG_FSL_DDR3)
 727        popts->mirrored_dimm = pdimm[0].mirrored_dimm;
 728#endif
 729
 730        /* Global Timing Parameters. */
 731        debug("mclk_ps = %u ps\n", get_memory_clk_period_ps());
 732
 733        /* Pick a caslat override. */
 734        popts->cas_latency_override = 0;
 735        popts->cas_latency_override_value = 3;
 736        if (popts->cas_latency_override) {
 737                debug("using caslat override value = %u\n",
 738                       popts->cas_latency_override_value);
 739        }
 740
 741        /* Decide whether to use the computed derated latency */
 742        popts->use_derated_caslat = 0;
 743
 744        /* Choose an additive latency. */
 745        popts->additive_latency_override = 0;
 746        popts->additive_latency_override_value = 3;
 747        if (popts->additive_latency_override) {
 748                debug("using additive latency override value = %u\n",
 749                       popts->additive_latency_override_value);
 750        }
 751
 752        /*
 753         * 2T_EN setting
 754         *
 755         * Factors to consider for 2T_EN:
 756         *      - number of DIMMs installed
 757         *      - number of components, number of active ranks
 758         *      - how much time you want to spend playing around
 759         */
 760        popts->twoT_en = 0;
 761        popts->threeT_en = 0;
 762
 763        /* for RDIMM, address parity enable */
 764        popts->ap_en = 1;
 765
 766        /*
 767         * BSTTOPRE precharge interval
 768         *
 769         * Set this to 0 for global auto precharge
 770         *
 771         * FIXME: Should this be configured in picoseconds?
 772         * Why it should be in ps:  better understanding of this
 773         * relative to actual DRAM timing parameters such as tRAS.
 774         * e.g. tRAS(min) = 40 ns
 775         */
 776        popts->bstopre = 0x100;
 777
 778        /* Minimum CKE pulse width -- tCKE(MIN) */
 779        popts->tCKE_clock_pulse_width_ps
 780                = mclk_to_picos(FSL_DDR_MIN_TCKE_PULSE_WIDTH_DDR);
 781
 782        /*
 783         * Window for four activates -- tFAW
 784         *
 785         * FIXME: UM: applies only to DDR2/DDR3 with eight logical banks only
 786         * FIXME: varies depending upon number of column addresses or data
 787         * FIXME: width, was considering looking at pdimm->primary_sdram_width
 788         */
 789#if defined(CONFIG_FSL_DDR1)
 790        popts->tFAW_window_four_activates_ps = mclk_to_picos(1);
 791
 792#elif defined(CONFIG_FSL_DDR2)
 793        /*
 794         * x4/x8;  some datasheets have 35000
 795         * x16 wide columns only?  Use 50000?
 796         */
 797        popts->tFAW_window_four_activates_ps = 37500;
 798
 799#elif defined(CONFIG_FSL_DDR3)
 800        popts->tFAW_window_four_activates_ps = pdimm[0].tFAW_ps;
 801#endif
 802        popts->zq_en = 0;
 803        popts->wrlvl_en = 0;
 804#if defined(CONFIG_FSL_DDR3)
 805        /*
 806         * due to ddr3 dimm is fly-by topology
 807         * we suggest to enable write leveling to
 808         * meet the tQDSS under different loading.
 809         */
 810        popts->wrlvl_en = 1;
 811        popts->zq_en = 1;
 812        popts->wrlvl_override = 0;
 813#endif
 814
 815        /*
 816         * Check interleaving configuration from environment.
 817         * Please refer to doc/README.fsl-ddr for the detail.
 818         *
 819         * If memory controller interleaving is enabled, then the data
 820         * bus widths must be programmed identically for all memory controllers.
 821         *
 822         * XXX: Attempt to set all controllers to the same chip select
 823         * interleaving mode. It will do a best effort to get the
 824         * requested ranks interleaved together such that the result
 825         * should be a subset of the requested configuration.
 826         */
 827#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
 828        if (!hwconfig_sub_f("fsl_ddr", "ctlr_intlv", buf))
 829                goto done;
 830
 831        if (pdimm[0].n_ranks == 0) {
 832                printf("There is no rank on CS0 for controller %d.\n", ctrl_num);
 833                popts->memctl_interleaving = 0;
 834                goto done;
 835        }
 836        popts->memctl_interleaving = 1;
 837        /*
 838         * test null first. if CONFIG_HWCONFIG is not defined
 839         * hwconfig_arg_cmp returns non-zero
 840         */
 841        if (hwconfig_subarg_cmp_f("fsl_ddr", "ctlr_intlv",
 842                                    "null", buf)) {
 843                popts->memctl_interleaving = 0;
 844                debug("memory controller interleaving disabled.\n");
 845        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 846                                        "ctlr_intlv",
 847                                        "cacheline", buf)) {
 848                popts->memctl_interleaving_mode =
 849                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 850                        0 : FSL_DDR_CACHE_LINE_INTERLEAVING;
 851                popts->memctl_interleaving =
 852                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 853                        0 : 1;
 854        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 855                                        "ctlr_intlv",
 856                                        "page", buf)) {
 857                popts->memctl_interleaving_mode =
 858                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 859                        0 : FSL_DDR_PAGE_INTERLEAVING;
 860                popts->memctl_interleaving =
 861                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 862                        0 : 1;
 863        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 864                                        "ctlr_intlv",
 865                                        "bank", buf)) {
 866                popts->memctl_interleaving_mode =
 867                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 868                        0 : FSL_DDR_BANK_INTERLEAVING;
 869                popts->memctl_interleaving =
 870                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 871                        0 : 1;
 872        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 873                                        "ctlr_intlv",
 874                                        "superbank", buf)) {
 875                popts->memctl_interleaving_mode =
 876                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 877                        0 : FSL_DDR_SUPERBANK_INTERLEAVING;
 878                popts->memctl_interleaving =
 879                        ((CONFIG_NUM_DDR_CONTROLLERS == 3) && ctrl_num == 2) ?
 880                        0 : 1;
 881#if (CONFIG_NUM_DDR_CONTROLLERS == 3)
 882        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 883                                        "ctlr_intlv",
 884                                        "3way_1KB", buf)) {
 885                popts->memctl_interleaving_mode =
 886                        FSL_DDR_3WAY_1KB_INTERLEAVING;
 887        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 888                                        "ctlr_intlv",
 889                                        "3way_4KB", buf)) {
 890                popts->memctl_interleaving_mode =
 891                        FSL_DDR_3WAY_4KB_INTERLEAVING;
 892        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 893                                        "ctlr_intlv",
 894                                        "3way_8KB", buf)) {
 895                popts->memctl_interleaving_mode =
 896                        FSL_DDR_3WAY_8KB_INTERLEAVING;
 897#elif (CONFIG_NUM_DDR_CONTROLLERS == 4)
 898        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 899                                        "ctlr_intlv",
 900                                        "4way_1KB", buf)) {
 901                popts->memctl_interleaving_mode =
 902                        FSL_DDR_4WAY_1KB_INTERLEAVING;
 903        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 904                                        "ctlr_intlv",
 905                                        "4way_4KB", buf)) {
 906                popts->memctl_interleaving_mode =
 907                        FSL_DDR_4WAY_4KB_INTERLEAVING;
 908        } else if (hwconfig_subarg_cmp_f("fsl_ddr",
 909                                        "ctlr_intlv",
 910                                        "4way_8KB", buf)) {
 911                popts->memctl_interleaving_mode =
 912                        FSL_DDR_4WAY_8KB_INTERLEAVING;
 913#endif
 914        } else {
 915                popts->memctl_interleaving = 0;
 916                printf("hwconfig has unrecognized parameter for ctlr_intlv.\n");
 917        }
 918done:
 919#endif
 920        if ((hwconfig_sub_f("fsl_ddr", "bank_intlv", buf)) &&
 921                (CONFIG_CHIP_SELECTS_PER_CTRL > 1)) {
 922                /* test null first. if CONFIG_HWCONFIG is not defined,
 923                 * hwconfig_subarg_cmp_f returns non-zero */
 924                if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
 925                                            "null", buf))
 926                        debug("bank interleaving disabled.\n");
 927                else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
 928                                                 "cs0_cs1", buf))
 929                        popts->ba_intlv_ctl = FSL_DDR_CS0_CS1;
 930                else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
 931                                                 "cs2_cs3", buf))
 932                        popts->ba_intlv_ctl = FSL_DDR_CS2_CS3;
 933                else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
 934                                                 "cs0_cs1_and_cs2_cs3", buf))
 935                        popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_AND_CS2_CS3;
 936                else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
 937                                                 "cs0_cs1_cs2_cs3", buf))
 938                        popts->ba_intlv_ctl = FSL_DDR_CS0_CS1_CS2_CS3;
 939                else if (hwconfig_subarg_cmp_f("fsl_ddr", "bank_intlv",
 940                                                "auto", buf))
 941                        popts->ba_intlv_ctl = auto_bank_intlv(pdimm);
 942                else
 943                        printf("hwconfig has unrecognized parameter for bank_intlv.\n");
 944                switch (popts->ba_intlv_ctl & FSL_DDR_CS0_CS1_CS2_CS3) {
 945                case FSL_DDR_CS0_CS1_CS2_CS3:
 946#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
 947                        if (pdimm[0].n_ranks < 4) {
 948                                popts->ba_intlv_ctl = 0;
 949                                printf("Not enough bank(chip-select) for "
 950                                        "CS0+CS1+CS2+CS3 on controller %d, "
 951                                        "interleaving disabled!\n", ctrl_num);
 952                        }
 953#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
 954#ifdef CONFIG_FSL_DDR_FIRST_SLOT_QUAD_CAPABLE
 955                        if (pdimm[0].n_ranks == 4)
 956                                break;
 957#endif
 958                        if ((pdimm[0].n_ranks < 2) && (pdimm[1].n_ranks < 2)) {
 959                                popts->ba_intlv_ctl = 0;
 960                                printf("Not enough bank(chip-select) for "
 961                                        "CS0+CS1+CS2+CS3 on controller %d, "
 962                                        "interleaving disabled!\n", ctrl_num);
 963                        }
 964                        if (pdimm[0].capacity != pdimm[1].capacity) {
 965                                popts->ba_intlv_ctl = 0;
 966                                printf("Not identical DIMM size for "
 967                                        "CS0+CS1+CS2+CS3 on controller %d, "
 968                                        "interleaving disabled!\n", ctrl_num);
 969                        }
 970#endif
 971                        break;
 972                case FSL_DDR_CS0_CS1:
 973                        if (pdimm[0].n_ranks < 2) {
 974                                popts->ba_intlv_ctl = 0;
 975                                printf("Not enough bank(chip-select) for "
 976                                        "CS0+CS1 on controller %d, "
 977                                        "interleaving disabled!\n", ctrl_num);
 978                        }
 979                        break;
 980                case FSL_DDR_CS2_CS3:
 981#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
 982                        if (pdimm[0].n_ranks < 4) {
 983                                popts->ba_intlv_ctl = 0;
 984                                printf("Not enough bank(chip-select) for CS2+CS3 "
 985                                        "on controller %d, interleaving disabled!\n", ctrl_num);
 986                        }
 987#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
 988                        if (pdimm[1].n_ranks < 2) {
 989                                popts->ba_intlv_ctl = 0;
 990                                printf("Not enough bank(chip-select) for CS2+CS3 "
 991                                        "on controller %d, interleaving disabled!\n", ctrl_num);
 992                        }
 993#endif
 994                        break;
 995                case FSL_DDR_CS0_CS1_AND_CS2_CS3:
 996#if (CONFIG_DIMM_SLOTS_PER_CTLR == 1)
 997                        if (pdimm[0].n_ranks < 4) {
 998                                popts->ba_intlv_ctl = 0;
 999                                printf("Not enough bank(CS) for CS0+CS1 and "
1000                                        "CS2+CS3 on controller %d, "
1001                                        "interleaving disabled!\n", ctrl_num);
1002                        }
1003#elif (CONFIG_DIMM_SLOTS_PER_CTLR == 2)
1004                        if ((pdimm[0].n_ranks < 2) || (pdimm[1].n_ranks < 2)) {
1005                                popts->ba_intlv_ctl = 0;
1006                                printf("Not enough bank(CS) for CS0+CS1 and "
1007                                        "CS2+CS3 on controller %d, "
1008                                        "interleaving disabled!\n", ctrl_num);
1009                        }
1010#endif
1011                        break;
1012                default:
1013                        popts->ba_intlv_ctl = 0;
1014                        break;
1015                }
1016        }
1017
1018        if (hwconfig_sub_f("fsl_ddr", "addr_hash", buf)) {
1019                if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash", "null", buf))
1020                        popts->addr_hash = 0;
1021                else if (hwconfig_subarg_cmp_f("fsl_ddr", "addr_hash",
1022                                               "true", buf))
1023                        popts->addr_hash = 1;
1024        }
1025
1026        if (pdimm[0].n_ranks == 4)
1027                popts->quad_rank_present = 1;
1028
1029        ddr_freq = get_ddr_freq(0) / 1000000;
1030        if (popts->registered_dimm_en) {
1031                popts->rcw_override = 1;
1032                popts->rcw_1 = 0x000a5a00;
1033                if (ddr_freq <= 800)
1034                        popts->rcw_2 = 0x00000000;
1035                else if (ddr_freq <= 1066)
1036                        popts->rcw_2 = 0x00100000;
1037                else if (ddr_freq <= 1333)
1038                        popts->rcw_2 = 0x00200000;
1039                else
1040                        popts->rcw_2 = 0x00300000;
1041        }
1042
1043        fsl_ddr_board_options(popts, pdimm, ctrl_num);
1044
1045        return 0;
1046}
1047
1048void check_interleaving_options(fsl_ddr_info_t *pinfo)
1049{
1050        int i, j, k, check_n_ranks, intlv_invalid = 0;
1051        unsigned int check_intlv, check_n_row_addr, check_n_col_addr;
1052        unsigned long long check_rank_density;
1053        struct dimm_params_s *dimm;
1054        /*
1055         * Check if all controllers are configured for memory
1056         * controller interleaving. Identical dimms are recommended. At least
1057         * the size, row and col address should be checked.
1058         */
1059        j = 0;
1060        check_n_ranks = pinfo->dimm_params[0][0].n_ranks;
1061        check_rank_density = pinfo->dimm_params[0][0].rank_density;
1062        check_n_row_addr =  pinfo->dimm_params[0][0].n_row_addr;
1063        check_n_col_addr = pinfo->dimm_params[0][0].n_col_addr;
1064        check_intlv = pinfo->memctl_opts[0].memctl_interleaving_mode;
1065        for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
1066                dimm = &pinfo->dimm_params[i][0];
1067                if (!pinfo->memctl_opts[i].memctl_interleaving) {
1068                        continue;
1069                } else if (((check_rank_density != dimm->rank_density) ||
1070                     (check_n_ranks != dimm->n_ranks) ||
1071                     (check_n_row_addr != dimm->n_row_addr) ||
1072                     (check_n_col_addr != dimm->n_col_addr) ||
1073                     (check_intlv !=
1074                        pinfo->memctl_opts[i].memctl_interleaving_mode))){
1075                        intlv_invalid = 1;
1076                        break;
1077                } else {
1078                        j++;
1079                }
1080
1081        }
1082        if (intlv_invalid) {
1083                for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
1084                        pinfo->memctl_opts[i].memctl_interleaving = 0;
1085                printf("Not all DIMMs are identical. "
1086                        "Memory controller interleaving disabled.\n");
1087        } else {
1088                switch (check_intlv) {
1089                case FSL_DDR_CACHE_LINE_INTERLEAVING:
1090                case FSL_DDR_PAGE_INTERLEAVING:
1091                case FSL_DDR_BANK_INTERLEAVING:
1092                case FSL_DDR_SUPERBANK_INTERLEAVING:
1093                        if (3 == CONFIG_NUM_DDR_CONTROLLERS)
1094                                k = 2;
1095                        else
1096                                k = CONFIG_NUM_DDR_CONTROLLERS;
1097                        break;
1098                case FSL_DDR_3WAY_1KB_INTERLEAVING:
1099                case FSL_DDR_3WAY_4KB_INTERLEAVING:
1100                case FSL_DDR_3WAY_8KB_INTERLEAVING:
1101                case FSL_DDR_4WAY_1KB_INTERLEAVING:
1102                case FSL_DDR_4WAY_4KB_INTERLEAVING:
1103                case FSL_DDR_4WAY_8KB_INTERLEAVING:
1104                default:
1105                        k = CONFIG_NUM_DDR_CONTROLLERS;
1106                        break;
1107                }
1108                debug("%d of %d controllers are interleaving.\n", j, k);
1109                if (j && (j != k)) {
1110                        for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
1111                                pinfo->memctl_opts[i].memctl_interleaving = 0;
1112                        printf("Not all controllers have compatible "
1113                                "interleaving mode. All disabled.\n");
1114                }
1115        }
1116        debug("Checking interleaving options completed\n");
1117}
1118
1119int fsl_use_spd(void)
1120{
1121        int use_spd = 0;
1122
1123#ifdef CONFIG_DDR_SPD
1124        char buffer[HWCONFIG_BUFFER_SIZE];
1125        char *buf = NULL;
1126
1127        /*
1128         * Extract hwconfig from environment since we have not properly setup
1129         * the environment but need it for ddr config params
1130         */
1131        if (getenv_f("hwconfig", buffer, sizeof(buffer)) > 0)
1132                buf = buffer;
1133
1134        /* if hwconfig is not enabled, or "sdram" is not defined, use spd */
1135        if (hwconfig_sub_f("fsl_ddr", "sdram", buf)) {
1136                if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram", "spd", buf))
1137                        use_spd = 1;
1138                else if (hwconfig_subarg_cmp_f("fsl_ddr", "sdram",
1139                                               "fixed", buf))
1140                        use_spd = 0;
1141                else
1142                        use_spd = 1;
1143        } else
1144                use_spd = 1;
1145#endif
1146
1147        return use_spd;
1148}
1149