uboot/board/tqc/tqm834x/tqm834x.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2005
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 *
  23 */
  24
  25#include <common.h>
  26#include <ioports.h>
  27#include <mpc83xx.h>
  28#include <asm/mpc8349_pci.h>
  29#include <i2c.h>
  30#include <miiphy.h>
  31#include <asm/mmu.h>
  32#include <pci.h>
  33#include <flash.h>
  34#include <mtd/cfi_flash.h>
  35
  36DECLARE_GLOBAL_DATA_PTR;
  37
  38#define IOSYNC                  asm("eieio")
  39#define ISYNC                   asm("isync")
  40#define SYNC                    asm("sync")
  41#define FPW                     FLASH_PORT_WIDTH
  42#define FPWV                    FLASH_PORT_WIDTHV
  43
  44#define DDR_MAX_SIZE_PER_CS     0x20000000
  45
  46#if defined(DDR_CASLAT_20)
  47#define TIMING_CASLAT           TIMING_CFG1_CASLAT_20
  48#define MODE_CASLAT             DDR_MODE_CASLAT_20
  49#else
  50#define TIMING_CASLAT           TIMING_CFG1_CASLAT_25
  51#define MODE_CASLAT             DDR_MODE_CASLAT_25
  52#endif
  53
  54#define INITIAL_CS_CONFIG       (CSCONFIG_EN | CSCONFIG_ROW_BIT_12 | \
  55                                CSCONFIG_COL_BIT_9)
  56
  57/* External definitions */
  58ulong flash_get_size (ulong base, int banknum);
  59
  60/* Local functions */
  61static int detect_num_flash_banks(void);
  62static long int get_ddr_bank_size(short cs, volatile long *base);
  63static void set_cs_bounds(short cs, long base, long size);
  64static void set_cs_config(short cs, long config);
  65static void set_ddr_config(void);
  66
  67/* Local variable */
  68static volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
  69
  70/**************************************************************************
  71 * Board initialzation after relocation to RAM. Used to detect the number
  72 * of Flash banks on TQM834x.
  73 */
  74int board_early_init_r (void) {
  75        /* sanity check, IMMARBAR should be mirrored at offset zero of IMMR */
  76        if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
  77                return 0;
  78
  79        /* detect the number of Flash banks */
  80        return detect_num_flash_banks();
  81}
  82
  83/**************************************************************************
  84 * DRAM initalization and size detection
  85 */
  86phys_size_t initdram (int board_type)
  87{
  88        long bank_size;
  89        long size;
  90        int cs;
  91
  92        /* during size detection, set up the max DDRLAW size */
  93        im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_BASE;
  94        im->sysconf.ddrlaw[0].ar = (LAWAR_EN | LAWAR_SIZE_2G);
  95
  96        /* set CS bounds to maximum size */
  97        for(cs = 0; cs < 4; ++cs) {
  98                set_cs_bounds(cs,
  99                        CONFIG_SYS_DDR_BASE + (cs * DDR_MAX_SIZE_PER_CS),
 100                        DDR_MAX_SIZE_PER_CS);
 101
 102                set_cs_config(cs, INITIAL_CS_CONFIG);
 103        }
 104
 105        /* configure ddr controller */
 106        set_ddr_config();
 107
 108        udelay(200);
 109
 110        /* enable DDR controller */
 111        im->ddr.sdram_cfg = (SDRAM_CFG_MEM_EN |
 112                SDRAM_CFG_SREN |
 113                SDRAM_CFG_SDRAM_TYPE_DDR1);
 114        SYNC;
 115
 116        /* size detection */
 117        debug("\n");
 118        size = 0;
 119        for(cs = 0; cs < 4; ++cs) {
 120                debug("\nDetecting Bank%d\n", cs);
 121
 122                bank_size = get_ddr_bank_size(cs,
 123                        (volatile long*)(CONFIG_SYS_DDR_BASE + size));
 124                size += bank_size;
 125
 126                debug("DDR Bank%d size: %d MiB\n\n", cs, bank_size >> 20);
 127
 128                /* exit if less than one bank */
 129                if(size < DDR_MAX_SIZE_PER_CS) break;
 130        }
 131
 132        return size;
 133}
 134
 135/**************************************************************************
 136 * checkboard()
 137 */
 138int checkboard (void)
 139{
 140        puts("Board: TQM834x\n");
 141
 142#ifdef CONFIG_PCI
 143        volatile immap_t * immr;
 144        u32 w, f;
 145
 146        immr = (immap_t *)CONFIG_SYS_IMMR;
 147        if (!(immr->reset.rcwh & HRCWH_PCI_HOST)) {
 148                printf("PCI:   NOT in host mode..?!\n");
 149                return 0;
 150        }
 151
 152        /* get bus width */
 153        w = 32;
 154        if (immr->reset.rcwh & HRCWH_64_BIT_PCI)
 155                w = 64;
 156
 157        /* get clock */
 158        f = gd->pci_clk;
 159
 160        printf("PCI1:  %d bit, %d MHz\n", w, f / 1000000);
 161#else
 162        printf("PCI:   disabled\n");
 163#endif
 164        return 0;
 165}
 166
 167
 168/**************************************************************************
 169 *
 170 * Local functions
 171 *
 172 *************************************************************************/
 173
 174/**************************************************************************
 175 * Detect the number of flash banks (1 or 2). Store it in
 176 * a global variable tqm834x_num_flash_banks.
 177 * Bank detection code based on the Monitor code.
 178 */
 179static int detect_num_flash_banks(void)
 180{
 181        typedef unsigned long FLASH_PORT_WIDTH;
 182        typedef volatile unsigned long FLASH_PORT_WIDTHV;
 183        FPWV *bank1_base;
 184        FPWV *bank2_base;
 185        FPW bank1_read;
 186        FPW bank2_read;
 187        ulong bank1_size;
 188        ulong bank2_size;
 189        ulong total_size;
 190
 191        cfi_flash_num_flash_banks = 2;  /* assume two banks */
 192
 193        /* Get bank 1 and 2 information */
 194        bank1_size = flash_get_size(CONFIG_SYS_FLASH_BASE, 0);
 195        debug("Bank1 size: %lu\n", bank1_size);
 196        bank2_size = flash_get_size(CONFIG_SYS_FLASH_BASE + bank1_size, 1);
 197        debug("Bank2 size: %lu\n", bank2_size);
 198        total_size = bank1_size + bank2_size;
 199
 200        if (bank2_size > 0) {
 201                /* Seems like we've got bank 2, but maybe it's mirrored 1 */
 202
 203                /* Set the base addresses */
 204                bank1_base = (FPWV *) (CONFIG_SYS_FLASH_BASE);
 205                bank2_base = (FPWV *) (CONFIG_SYS_FLASH_BASE + bank1_size);
 206
 207                /* Put bank 2 into CFI command mode and read */
 208                bank2_base[0x55] = 0x00980098;
 209                IOSYNC;
 210                ISYNC;
 211                bank2_read = bank2_base[0x10];
 212
 213                /* Read from bank 1 (it's in read mode) */
 214                bank1_read = bank1_base[0x10];
 215
 216                /* Reset Flash */
 217                bank1_base[0] = 0x00F000F0;
 218                bank2_base[0] = 0x00F000F0;
 219
 220                if (bank2_read == bank1_read) {
 221                        /*
 222                         * Looks like just one bank, but not sure yet. Let's
 223                         * read from bank 2 in autosoelect mode.
 224                         */
 225                        bank2_base[0x0555] = 0x00AA00AA;
 226                        bank2_base[0x02AA] = 0x00550055;
 227                        bank2_base[0x0555] = 0x00900090;
 228                        IOSYNC;
 229                        ISYNC;
 230                        bank2_read = bank2_base[0x10];
 231
 232                        /* Read from bank 1 (it's in read mode) */
 233                        bank1_read = bank1_base[0x10];
 234
 235                        /* Reset Flash */
 236                        bank1_base[0] = 0x00F000F0;
 237                        bank2_base[0] = 0x00F000F0;
 238
 239                        if (bank2_read == bank1_read) {
 240                                /*
 241                                 * In both CFI command and autoselect modes,
 242                                 * we got the some data reading from Flash.
 243                                 * There is only one mirrored bank.
 244                                 */
 245                                cfi_flash_num_flash_banks = 1;
 246                                total_size = bank1_size;
 247                        }
 248                }
 249        }
 250
 251        debug("Number of flash banks detected: %d\n", cfi_flash_num_flash_banks);
 252
 253        /* set OR0 and BR0 */
 254        set_lbc_or(0, CONFIG_SYS_OR_TIMING_FLASH |
 255                   (-(total_size) & OR_GPCM_AM));
 256        set_lbc_br(0, (CONFIG_SYS_FLASH_BASE & BR_BA) |
 257                   (BR_MS_GPCM | BR_PS_32 | BR_V));
 258
 259        return (0);
 260}
 261
 262/*************************************************************************
 263 * Detect the size of a ddr bank. Sets CS bounds and CS config accordingly.
 264 */
 265static long int get_ddr_bank_size(short cs, volatile long *base)
 266{
 267        /* This array lists all valid DDR SDRAM configurations, with
 268         * Bank sizes in bytes. (Refer to Table 9-27 in the MPC8349E RM).
 269         * The last entry has to to have size equal 0 and is igonred during
 270         * autodection. Bank sizes must be in increasing order of size
 271         */
 272        struct {
 273                long row;
 274                long col;
 275                long size;
 276        } conf[] = {
 277                {CSCONFIG_ROW_BIT_12,   CSCONFIG_COL_BIT_8,     32 << 20},
 278                {CSCONFIG_ROW_BIT_12,   CSCONFIG_COL_BIT_9,     64 << 20},
 279                {CSCONFIG_ROW_BIT_12,   CSCONFIG_COL_BIT_10,    128 << 20},
 280                {CSCONFIG_ROW_BIT_13,   CSCONFIG_COL_BIT_9,     128 << 20},
 281                {CSCONFIG_ROW_BIT_13,   CSCONFIG_COL_BIT_10,    256 << 20},
 282                {CSCONFIG_ROW_BIT_13,   CSCONFIG_COL_BIT_11,    512 << 20},
 283                {CSCONFIG_ROW_BIT_14,   CSCONFIG_COL_BIT_10,    512 << 20},
 284                {CSCONFIG_ROW_BIT_14,   CSCONFIG_COL_BIT_11,    1024 << 20},
 285                {0,                     0,                      0}
 286        };
 287
 288        int i;
 289        int detected;
 290        long size;
 291
 292        detected = -1;
 293        for(i = 0; conf[i].size != 0; ++i) {
 294
 295                /* set sdram bank configuration */
 296                set_cs_config(cs, CSCONFIG_EN | conf[i].col | conf[i].row);
 297
 298                debug("Getting RAM size...\n");
 299                size = get_ram_size(base, DDR_MAX_SIZE_PER_CS);
 300
 301                if((size == conf[i].size) && (i == detected + 1))
 302                        detected = i;
 303
 304                debug("Trying %ld x %ld (%ld MiB) at addr %p, detected: %ld MiB\n",
 305                        conf[i].row,
 306                        conf[i].col,
 307                        conf[i].size >> 20,
 308                        base,
 309                        size >> 20);
 310        }
 311
 312        if(detected == -1){
 313                /* disable empty cs */
 314                debug("\nNo valid configurations for CS%d, disabling...\n", cs);
 315                set_cs_config(cs, 0);
 316                return 0;
 317        }
 318
 319        debug("\nDetected configuration %ld x %ld (%ld MiB) at addr %p\n",
 320                        conf[detected].row, conf[detected].col, conf[detected].size >> 20, base);
 321
 322        /* configure cs ro detected params */
 323        set_cs_config(cs, CSCONFIG_EN | conf[detected].row |
 324                        conf[detected].col);
 325
 326        set_cs_bounds(cs, (long)base, conf[detected].size);
 327
 328        return(conf[detected].size);
 329}
 330
 331/**************************************************************************
 332 * Sets DDR bank CS bounds.
 333 */
 334static void set_cs_bounds(short cs, long base, long size)
 335{
 336        debug("Setting bounds %08x, %08x for cs %d\n", base, size, cs);
 337        if(size == 0){
 338                im->ddr.csbnds[cs].csbnds = 0x00000000;
 339        } else {
 340                im->ddr.csbnds[cs].csbnds =
 341                        ((base >> CSBNDS_SA_SHIFT) & CSBNDS_SA) |
 342                        (((base + size - 1) >> CSBNDS_EA_SHIFT) &
 343                                CSBNDS_EA);
 344        }
 345        SYNC;
 346}
 347
 348/**************************************************************************
 349 * Sets DDR banks CS configuration.
 350 * config == 0x00000000 disables the CS.
 351 */
 352static void set_cs_config(short cs, long config)
 353{
 354        debug("Setting config %08x for cs %d\n", config, cs);
 355        im->ddr.cs_config[cs] = config;
 356        SYNC;
 357}
 358
 359/**************************************************************************
 360 * Sets DDR clocks, timings and configuration.
 361 */
 362static void set_ddr_config(void) {
 363        /* clock control */
 364        im->ddr.sdram_clk_cntl = DDR_SDRAM_CLK_CNTL_SS_EN |
 365                DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05;
 366        SYNC;
 367
 368        /* timing configuration */
 369        im->ddr.timing_cfg_1 =
 370                (4 << TIMING_CFG1_PRETOACT_SHIFT) |
 371                (7 << TIMING_CFG1_ACTTOPRE_SHIFT) |
 372                (4 << TIMING_CFG1_ACTTORW_SHIFT)  |
 373                (5 << TIMING_CFG1_REFREC_SHIFT)   |
 374                (3 << TIMING_CFG1_WRREC_SHIFT)    |
 375                (3 << TIMING_CFG1_ACTTOACT_SHIFT) |
 376                (1 << TIMING_CFG1_WRTORD_SHIFT)   |
 377                (TIMING_CFG1_CASLAT & TIMING_CASLAT);
 378
 379        im->ddr.timing_cfg_2 =
 380                TIMING_CFG2_CPO_DEF |
 381                (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT);
 382        SYNC;
 383
 384        /* don't enable DDR controller yet */
 385        im->ddr.sdram_cfg =
 386                SDRAM_CFG_SREN |
 387                SDRAM_CFG_SDRAM_TYPE_DDR1;
 388        SYNC;
 389
 390        /* Set SDRAM mode */
 391        im->ddr.sdram_mode =
 392                ((DDR_MODE_EXT_MODEREG | DDR_MODE_WEAK) <<
 393                        SDRAM_MODE_ESD_SHIFT) |
 394                ((DDR_MODE_MODEREG | DDR_MODE_BLEN_4) <<
 395                        SDRAM_MODE_SD_SHIFT) |
 396                ((DDR_MODE_CASLAT << SDRAM_MODE_SD_SHIFT) &
 397                        MODE_CASLAT);
 398        SYNC;
 399
 400        /* Set fast SDRAM refresh rate */
 401        im->ddr.sdram_interval =
 402                (DDR_REFINT_166MHZ_7US << SDRAM_INTERVAL_REFINT_SHIFT) |
 403                (DDR_BSTOPRE << SDRAM_INTERVAL_BSTOPRE_SHIFT);
 404        SYNC;
 405
 406        /* Workaround for DDR6 Erratum
 407         * see MPC8349E Device Errata Rev.8, 2/2006
 408         * This workaround influences the MPC internal "input enables"
 409         * dependent on CAS latency and MPC revision. According to errata
 410         * sheet the internal reserved registers for this workaround are
 411         * not available from revision 2.0 and up.
 412         */
 413
 414        /* Get REVID from register SPRIDR. Skip workaround if rev >= 2.0
 415         * (0x200)
 416         */
 417        if ((im->sysconf.spridr & SPRIDR_REVID) < 0x200) {
 418
 419                /* There is a internal reserved register at IMMRBAR+0x2F00
 420                 * which has to be written with a certain value defined by
 421                 * errata sheet.
 422                 */
 423                u32 *reserved_p = (u32 *)((u8 *)im + 0x2f00);
 424
 425#if defined(DDR_CASLAT_20)
 426                *reserved_p = 0x201c0000;
 427#else
 428                *reserved_p = 0x202c0000;
 429#endif
 430        }
 431}
 432
 433#ifdef CONFIG_OF_BOARD_SETUP
 434void ft_board_setup(void *blob, bd_t *bd)
 435{
 436        ft_cpu_setup(blob, bd);
 437
 438#ifdef CONFIG_PCI
 439        ft_pci_setup(blob, bd);
 440#endif  /* CONFIG_PCI */
 441}
 442#endif  /* CONFIG_OF_BOARD_SETUP */
 443