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