uboot/board/mucmc52/mucmc52.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003-2004
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * (C) Copyright 2004
   6 * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
   7 *
   8 * (C) Copyright 2004
   9 * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
  10 *
  11 * (C) Copyright 2008
  12 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  13 *
  14 * See file CREDITS for list of people who contributed to this
  15 * project.
  16 *
  17 * This program is free software; you can redistribute it and/or
  18 * modify it under the terms of the GNU General Public License as
  19 * published by the Free Software Foundation; either version 2 of
  20 * the License, or (at your option) any later version.
  21 *
  22 * This program is distributed in the hope that it will be useful,
  23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  25 * GNU General Public License for more details.
  26 *
  27 * You should have received a copy of the GNU General Public License
  28 * along with this program; if not, write to the Free Software
  29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  30 * MA 02111-1307 USA
  31 */
  32
  33#include <common.h>
  34#include <mpc5xxx.h>
  35#include <pci.h>
  36#include <malloc.h>
  37#include <asm/processor.h>
  38#include <asm/io.h>
  39
  40#ifndef CONFIG_SYS_RAMBOOT
  41static void sdram_start (int hi_addr)
  42{
  43        long hi_addr_bit = hi_addr ? 0x01000000 : 0;
  44
  45        /* unlock mode register */
  46        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
  47                (SDRAM_CONTROL | 0x80000000 | hi_addr_bit));
  48        __asm__ volatile ("sync");
  49
  50        /* precharge all banks */
  51        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
  52                (SDRAM_CONTROL | 0x80000002 | hi_addr_bit));
  53        __asm__ volatile ("sync");
  54
  55#if SDRAM_DDR
  56        /* set mode register: extended mode */
  57        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_MODE, (SDRAM_EMODE));
  58        __asm__ volatile ("sync");
  59
  60        /* set mode register: reset DLL */
  61        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_MODE,
  62                (SDRAM_MODE | 0x04000000));
  63        __asm__ volatile ("sync");
  64#endif
  65
  66        /* precharge all banks */
  67        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
  68                (SDRAM_CONTROL | 0x80000002 | hi_addr_bit));
  69        __asm__ volatile ("sync");
  70
  71        /* auto refresh */
  72        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
  73                (SDRAM_CONTROL | 0x80000004 | hi_addr_bit));
  74        __asm__ volatile ("sync");
  75
  76        /* set mode register */
  77        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_MODE, (SDRAM_MODE));
  78        __asm__ volatile ("sync");
  79
  80        /* normal operation */
  81        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CTRL,
  82                (SDRAM_CONTROL | hi_addr_bit));
  83        __asm__ volatile ("sync");
  84}
  85#endif
  86
  87/*
  88 * ATTENTION: Although partially referenced initdram does NOT make real use
  89 *            use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
  90 *            is something else than 0x00000000.
  91 */
  92
  93phys_size_t initdram (int board_type)
  94{
  95        ulong dramsize = 0;
  96        ulong dramsize2 = 0;
  97        uint svr, pvr;
  98
  99#ifndef CONFIG_SYS_RAMBOOT
 100        ulong test1, test2;
 101
 102        /* setup SDRAM chip selects */
 103        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG, 0x0000001c); /* 512MB at 0x0 */
 104        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG, 0x80000000);/* disabled */
 105        __asm__ volatile ("sync");
 106
 107        /* setup config registers */
 108        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CONFIG1, SDRAM_CONFIG1);
 109        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CONFIG2, SDRAM_CONFIG2);
 110        __asm__ volatile ("sync");
 111
 112#if SDRAM_DDR
 113        /* set tap delay */
 114        out_be32 ((unsigned __iomem *)MPC5XXX_CDM_PORCFG, SDRAM_TAPDELAY);
 115        __asm__ volatile ("sync");
 116#endif
 117
 118        /* find RAM size using SDRAM CS0 only */
 119        sdram_start (0);
 120        test1 = get_ram_size ((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
 121        sdram_start(1);
 122        test2 = get_ram_size ((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
 123        if (test1 > test2) {
 124                sdram_start (0);
 125                dramsize = test1;
 126        } else {
 127                dramsize = test2;
 128        }
 129
 130        /* memory smaller than 1MB is impossible */
 131        if (dramsize < (1 << 20)) {
 132                dramsize = 0;
 133        }
 134
 135        /* set SDRAM CS0 size according to the amount of RAM found */
 136        if (dramsize > 0) {
 137                out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG,
 138                        (0x13 + __builtin_ffs(dramsize >> 20) - 1));
 139        } else {
 140                out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG, 0); /* disabled */
 141        }
 142
 143        /* let SDRAM CS1 start right after CS0 */
 144        out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG, (dramsize + 0x0000001c));/*512MB*/
 145
 146        /* find RAM size using SDRAM CS1 only */
 147        if (!dramsize)
 148                sdram_start (0);
 149        test2 = test1 = get_ram_size ((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
 150        if (!dramsize) {
 151                sdram_start (1);
 152                test2 = get_ram_size ((long *)(CONFIG_SYS_SDRAM_BASE + dramsize), 0x20000000);
 153        }
 154        if (test1 > test2) {
 155                sdram_start (0);
 156                dramsize2 = test1;
 157        } else {
 158                dramsize2 = test2;
 159        }
 160
 161        /* memory smaller than 1MB is impossible */
 162        if (dramsize2 < (1 << 20)) {
 163                dramsize2 = 0;
 164        }
 165
 166        /* set SDRAM CS1 size according to the amount of RAM found */
 167        if (dramsize2 > 0) {
 168                out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG,
 169                        (dramsize | (0x13 + __builtin_ffs(dramsize2 >> 20) - 1)));
 170        } else {
 171                out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG, dramsize); /* disabled */
 172        }
 173
 174#else /* CONFIG_SYS_RAMBOOT */
 175
 176        /* retrieve size of memory connected to SDRAM CS0 */
 177        dramsize = in_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS0CFG) & 0xFF;
 178        if (dramsize >= 0x13) {
 179                dramsize = (1 << (dramsize - 0x13)) << 20;
 180        } else {
 181                dramsize = 0;
 182        }
 183
 184        /* retrieve size of memory connected to SDRAM CS1 */
 185        dramsize2 = in_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_CS1CFG) & 0xFF;
 186        if (dramsize2 >= 0x13) {
 187                dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
 188        } else {
 189                dramsize2 = 0;
 190        }
 191
 192#endif /* CONFIG_SYS_RAMBOOT */
 193
 194         /*
 195         * On MPC5200B we need to set the special configuration delay in the
 196         * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
 197         * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
 198         *
 199         * "The SDelay should be written to a value of 0x00000004. It is
 200         * required to account for changes caused by normal wafer processing
 201         * parameters."
 202         */
 203        svr = get_svr();
 204        pvr = get_pvr();
 205        if ((SVR_MJREV(svr) >= 2) &&
 206            (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4)) {
 207
 208                out_be32 ((unsigned __iomem *)MPC5XXX_SDRAM_SDELAY, 0x04);
 209                __asm__ volatile ("sync");
 210        }
 211
 212        return dramsize + dramsize2;
 213}
 214
 215int checkboard (void)
 216{
 217        puts ("Board: MUC.MC-52 HW WDT ");
 218#if defined(CONFIG_HW_WATCHDOG)
 219        puts ("enabled\n");
 220#else
 221        puts ("disabled\n");
 222#endif
 223        return 0;
 224}
 225
 226#ifdef CONFIG_PREBOOT
 227
 228static uchar kbd_magic_prefix[]         = "key_magic";
 229static uchar kbd_command_prefix[]       = "key_cmd";
 230
 231#define S1_ROT  0xf0
 232#define S2_Q    0x40
 233#define S2_M    0x20
 234
 235struct kbd_data_t {
 236        char s1;
 237        char s2;
 238};
 239
 240struct kbd_data_t* get_keys (struct kbd_data_t *kbd_data)
 241{
 242        kbd_data->s1 = in_8 ((volatile uchar*)CONFIG_SYS_STATUS1_BASE);
 243        kbd_data->s2 = in_8 ((volatile uchar*)CONFIG_SYS_STATUS2_BASE);
 244
 245        return kbd_data;
 246}
 247
 248static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
 249{
 250        char s1 = str[0];
 251        char s2;
 252
 253        if (s1 >= '0' && s1 <= '9')
 254                s1 -= '0';
 255        else if (s1 >= 'a' && s1 <= 'f')
 256                s1 = s1 - 'a' + 10;
 257        else if (s1 >= 'A' && s1 <= 'F')
 258                s1 = s1 - 'A' + 10;
 259        else
 260                return -1;
 261
 262        if (((S1_ROT & kbd_data->s1) >> 4) != s1)
 263                return -1;
 264
 265        s2 = (S2_Q | S2_M) & kbd_data->s2;
 266
 267        switch (str[1]) {
 268        case 'q':
 269        case 'Q':
 270                if (s2 == S2_Q)
 271                        return -1;
 272                break;
 273        case 'm':
 274        case 'M':
 275                if (s2 == S2_M)
 276                        return -1;
 277                break;
 278        case '\0':
 279                if (s2 == (S2_Q | S2_M))
 280                        return 0;
 281        default:
 282                return -1;
 283        }
 284
 285        if (str[2])
 286                return -1;
 287
 288        return 0;
 289}
 290
 291static char *key_match (const struct kbd_data_t *kbd_data)
 292{
 293        char magic[sizeof (kbd_magic_prefix) + 1];
 294        char *suffix;
 295        char *kbd_magic_keys;
 296
 297        /*
 298         * The following string defines the characters that can be appended
 299         * to "key_magic" to form the names of environment variables that
 300         * hold "magic" key codes, i. e. such key codes that can cause
 301         * pre-boot actions. If the string is empty (""), then only
 302         * "key_magic" is checked (old behaviour); the string "125" causes
 303         * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
 304         */
 305        if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
 306                kbd_magic_keys = "";
 307
 308        /* loop over all magic keys;
 309         * use '\0' suffix in case of empty string
 310         */
 311        for (suffix = kbd_magic_keys; *suffix ||
 312                     suffix == kbd_magic_keys; ++suffix) {
 313                sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
 314
 315                if (compare_magic(kbd_data, getenv(magic)) == 0) {
 316                        char cmd_name[sizeof (kbd_command_prefix) + 1];
 317                        char *cmd;
 318
 319                        sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
 320                        cmd = getenv (cmd_name);
 321
 322                        return (cmd);
 323                }
 324        }
 325
 326        return (NULL);
 327}
 328
 329#endif /* CONFIG_PREBOOT */
 330
 331int misc_init_r (void)
 332{
 333#ifdef CONFIG_PREBOOT
 334        struct kbd_data_t kbd_data;
 335        /* Decode keys */
 336        char *str = strdup (key_match (get_keys (&kbd_data)));
 337        /* Set or delete definition */
 338        setenv ("preboot", str);
 339        free (str);
 340#endif /* CONFIG_PREBOOT */
 341
 342        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x38), ' ');
 343        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x39), ' ');
 344        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3A), ' ');
 345        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3B), ' ');
 346        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3C), ' ');
 347        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3D), ' ');
 348        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3E), ' ');
 349        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3F), ' ');
 350
 351        return 0;
 352}
 353
 354int board_early_init_r (void)
 355{
 356        out_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_CFG, in_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_CFG) & ~0x1);
 357        out_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_START, START_REG(CONFIG_SYS_FLASH_BASE));
 358        out_be32 ((unsigned __iomem *)MPC5XXX_CS0_START, START_REG(CONFIG_SYS_FLASH_BASE));
 359        out_be32 ((unsigned __iomem *)MPC5XXX_BOOTCS_STOP,
 360                STOP_REG(CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_SIZE));
 361        out_be32 ((unsigned __iomem *)MPC5XXX_CS0_STOP,
 362                STOP_REG(CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_SIZE));
 363        return 0;
 364}
 365
 366int last_stage_init (void)
 367{
 368        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x38), 'M');
 369        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x39), 'U');
 370        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3A), 'C');
 371        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3B), '.');
 372        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3C), 'M');
 373        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3D), 'C');
 374        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3E), '5');
 375        out_8 ((volatile uchar *)(CONFIG_SYS_DISPLAY_BASE + 0x3F), '2');
 376
 377        return 0;
 378}
 379
 380#if defined(CONFIG_HW_WATCHDOG)
 381#define GPT_OUT_0       0x00000027
 382#define GPT_OUT_1       0x00000037
 383void hw_watchdog_reset (void)
 384{
 385        /* Trigger HW Watchdog with TIMER_0 */
 386        out_be32 ((unsigned __iomem *)MPC5XXX_GPT0_ENABLE, GPT_OUT_1);
 387        out_be32 ((unsigned __iomem *)MPC5XXX_GPT0_ENABLE, GPT_OUT_0);
 388}
 389#endif
 390
 391#ifdef  CONFIG_PCI
 392static struct pci_controller hose;
 393
 394extern void pci_mpc5xxx_init (struct pci_controller *);
 395
 396void pci_init_board (void)
 397{
 398        pci_mpc5xxx_init (&hose);
 399}
 400#endif
 401