uboot/board/r360mpi/r360mpi.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001-2003
   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#include <common.h>
  25#include <config.h>
  26#include <mpc8xx.h>
  27#include <i2c.h>
  28
  29#include <commproc.h>
  30#include <command.h>
  31#include <malloc.h>
  32
  33#include <linux/types.h>
  34#include <linux/string.h>       /* for strdup */
  35
  36
  37/*
  38 *  Memory Controller Using
  39 *
  40 *  CS0 - Flash memory          (0x40000000)
  41 *  CS1 - FLASH memory          (0x????????)
  42 *  CS2 - SDRAM                 (0x00000000)
  43 *  CS3 -
  44 *  CS4 -
  45 *  CS5 -
  46 *  CS6 - PCMCIA device
  47 *  CS7 - PCMCIA device
  48 */
  49
  50/* ------------------------------------------------------------------------- */
  51
  52#define _not_used_      0xffffffff
  53
  54const uint sdram_table[]=
  55{
  56        /* single read. (offset 0 in upm RAM) */
  57        0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
  58        0x1ff77c47,
  59
  60        /* MRS initialization (offset 5) */
  61
  62        0x1ff77c34, 0xefeabc34, 0x1fb57c35,
  63
  64        /* burst read. (offset 8 in upm RAM) */
  65        0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
  66        0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
  67        _not_used_, _not_used_, _not_used_, _not_used_,
  68        _not_used_, _not_used_, _not_used_, _not_used_,
  69
  70        /* single write. (offset 18 in upm RAM) */
  71        0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
  72        _not_used_, _not_used_, _not_used_, _not_used_,
  73
  74        /* burst write. (offset 20 in upm RAM) */
  75        0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
  76        0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
  77        _not_used_, _not_used_, _not_used_, _not_used_,
  78        _not_used_, _not_used_, _not_used_, _not_used_,
  79
  80        /* refresh. (offset 30 in upm RAM) */
  81        0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
  82        0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
  83        _not_used_, _not_used_, _not_used_, _not_used_,
  84
  85        /* exception. (offset 3c in upm RAM) */
  86        0x7ffffc07, _not_used_, _not_used_, _not_used_ };
  87
  88/* ------------------------------------------------------------------------- */
  89
  90/*
  91 * Check Board Identity:
  92 */
  93
  94int checkboard (void)
  95{
  96        puts ("Board: R360 MPI Board\n");
  97        return 0;
  98}
  99
 100/* ------------------------------------------------------------------------- */
 101
 102static long int dram_size (long int, long int *, long int);
 103
 104/* ------------------------------------------------------------------------- */
 105
 106phys_size_t initdram (int board_type)
 107{
 108        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 109        volatile memctl8xx_t *memctl = &immap->im_memctl;
 110        long int size8, size9;
 111        long int size_b0 = 0;
 112        unsigned long reg;
 113
 114        upmconfig (UPMA, (uint *) sdram_table,
 115                           sizeof (sdram_table) / sizeof (uint));
 116
 117        /*
 118         * Preliminary prescaler for refresh (depends on number of
 119         * banks): This value is selected for four cycles every 62.4 us
 120         * with two SDRAM banks or four cycles every 31.2 us with one
 121         * bank. It will be adjusted after memory sizing.
 122         */
 123        memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_8K;
 124
 125        memctl->memc_mar = 0x00000088;
 126
 127        /*
 128         * Map controller bank 2 to the SDRAM bank at
 129         * preliminary address - these have to be modified after the
 130         * SDRAM size has been determined.
 131         */
 132        memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM;
 133        memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM;
 134
 135        memctl->memc_mamr = CONFIG_SYS_MAMR_8COL & (~(MAMR_PTAE));      /* no refresh yet */
 136
 137        udelay (200);
 138
 139        /* perform SDRAM initializsation sequence */
 140
 141        memctl->memc_mcr = 0x80004105;  /* SDRAM bank 0 */
 142        udelay (200);
 143        memctl->memc_mcr = 0x80004230;  /* SDRAM bank 0 - execute twice */
 144        udelay (200);
 145
 146        memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
 147
 148        udelay (1000);
 149
 150        /*
 151         * Check Bank 2 Memory Size for re-configuration
 152         *
 153         * try 8 column mode
 154         */
 155        size8 = dram_size (CONFIG_SYS_MAMR_8COL, (long *) SDRAM_BASE2_PRELIM,
 156                                           SDRAM_MAX_SIZE);
 157
 158        udelay (1000);
 159
 160        /*
 161         * try 9 column mode
 162         */
 163        size9 = dram_size (CONFIG_SYS_MAMR_9COL, (long *) SDRAM_BASE2_PRELIM,
 164                                           SDRAM_MAX_SIZE);
 165
 166        if (size8 < size9) {            /* leave configuration at 9 columns */
 167                size_b0 = size9;
 168/*      debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);  */
 169        } else {                        /* back to 8 columns            */
 170                size_b0 = size8;
 171                memctl->memc_mamr = CONFIG_SYS_MAMR_8COL;
 172                udelay (500);
 173/*      debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);  */
 174        }
 175
 176        udelay (1000);
 177
 178        /*
 179         * Adjust refresh rate depending on SDRAM type, both banks
 180         * For types > 128 MBit leave it at the current (fast) rate
 181         */
 182        if ((size_b0 < 0x02000000)) {
 183                /* reduce to 15.6 us (62.4 us / quad) */
 184                memctl->memc_mptpr = CONFIG_SYS_MPTPR_2BK_4K;
 185                udelay (1000);
 186        }
 187
 188        /*
 189         * Final mapping
 190         */
 191
 192        memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CONFIG_SYS_OR_TIMING_SDRAM;
 193        memctl->memc_br1 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
 194
 195        /* adjust refresh rate depending on SDRAM type, one bank */
 196        reg = memctl->memc_mptpr;
 197        reg >>= 1;              /* reduce to CONFIG_SYS_MPTPR_1BK_8K / _4K */
 198        memctl->memc_mptpr = reg;
 199
 200        udelay (10000);
 201
 202#ifdef CONFIG_CAN_DRIVER
 203        /* Initialize OR3 / BR3 */
 204        memctl->memc_or3 = CONFIG_SYS_OR3_CAN;          /* switch GPLB_5 to GPLA_5 */
 205        memctl->memc_br3 = CONFIG_SYS_BR3_CAN;
 206
 207        /* Initialize MBMR */
 208        memctl->memc_mbmr = MBMR_GPL_B4DIS;     /* GPL_B4 works as UPWAITB */
 209
 210        /* Initialize UPMB for CAN: single read */
 211        memctl->memc_mdr = 0xFFFFC004;
 212        memctl->memc_mcr = 0x0100 | UPMB;
 213
 214        memctl->memc_mdr = 0x0FFFD004;
 215        memctl->memc_mcr = 0x0101 | UPMB;
 216
 217        memctl->memc_mdr = 0x0FFFC000;
 218        memctl->memc_mcr = 0x0102 | UPMB;
 219
 220        memctl->memc_mdr = 0x3FFFC004;
 221        memctl->memc_mcr = 0x0103 | UPMB;
 222
 223        memctl->memc_mdr = 0xFFFFDC05;
 224        memctl->memc_mcr = 0x0104 | UPMB;
 225
 226        /* Initialize UPMB for CAN: single write */
 227        memctl->memc_mdr = 0xFFFCC004;
 228        memctl->memc_mcr = 0x0118 | UPMB;
 229
 230        memctl->memc_mdr = 0xCFFCD004;
 231        memctl->memc_mcr = 0x0119 | UPMB;
 232
 233        memctl->memc_mdr = 0x0FFCC000;
 234        memctl->memc_mcr = 0x011A | UPMB;
 235
 236        memctl->memc_mdr = 0x7FFCC004;
 237        memctl->memc_mcr = 0x011B | UPMB;
 238
 239        memctl->memc_mdr = 0xFFFDCC05;
 240        memctl->memc_mcr = 0x011C | UPMB;
 241#endif
 242
 243        return (size_b0);
 244}
 245
 246/* ------------------------------------------------------------------------- */
 247
 248/*
 249 * Check memory range for valid RAM. A simple memory test determines
 250 * the actually available RAM size between addresses `base' and
 251 * `base + maxsize'. Some (not all) hardware errors are detected:
 252 * - short between address lines
 253 * - short between data lines
 254 */
 255
 256static long int dram_size (long int mamr_value,
 257                           long int *base, long int maxsize)
 258{
 259        volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 260        volatile memctl8xx_t *memctl = &immap->im_memctl;
 261
 262        memctl->memc_mamr = mamr_value;
 263
 264        return (get_ram_size(base, maxsize));
 265}
 266
 267/* ------------------------------------------------------------------------- */
 268
 269void r360_i2c_lcd_write (uchar data0, uchar data1)
 270{
 271        if (i2c_write (CONFIG_SYS_I2C_LCD_ADDR, data0, 1, &data1, 1)) {
 272                printf("Can't write lcd data 0x%02X 0x%02X.\n", data0, data1);
 273        }
 274}
 275
 276/* ------------------------------------------------------------------------- */
 277
 278/*-----------------------------------------------------------------------
 279 * Keyboard Controller
 280 */
 281
 282/* Number of bytes returned from Keyboard Controller */
 283#define KEYBD_KEY_MAX   16                              /* maximum key number */
 284#define KEYBD_DATALEN   ((KEYBD_KEY_MAX + 7) / 8)       /* normal key scan data */
 285
 286static uchar *key_match (uchar *);
 287
 288int misc_init_r (void)
 289{
 290        char kbd_data[KEYBD_DATALEN];
 291        char keybd_env[2 * KEYBD_DATALEN + 1];
 292        char *str;
 293        int i;
 294
 295        i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 296
 297        i2c_read (CONFIG_SYS_I2C_KEY_ADDR, 0, 0, (uchar *)kbd_data, KEYBD_DATALEN);
 298
 299        for (i = 0; i < KEYBD_DATALEN; ++i) {
 300                sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
 301        }
 302        setenv ("keybd", keybd_env);
 303
 304        str = strdup ((char *)key_match ((uchar *)keybd_env));  /* decode keys */
 305
 306#ifdef CONFIG_PREBOOT   /* automatically configure "preboot" command on key match */
 307        setenv ("preboot", str);        /* set or delete definition */
 308#endif /* CONFIG_PREBOOT */
 309        if (str != NULL) {
 310                free (str);
 311        }
 312
 313        return (0);
 314}
 315
 316/*-----------------------------------------------------------------------
 317 * Check if pressed key(s) match magic sequence,
 318 * and return the command string associated with that key(s).
 319 *
 320 * If no key press was decoded, NULL is returned.
 321 *
 322 * Note: the first character of the argument will be overwritten with
 323 * the "magic charcter code" of the decoded key(s), or '\0'.
 324 *
 325 *
 326 * Note: the string points to static environment data and must be
 327 * saved before you call any function that modifies the environment.
 328 */
 329#ifdef CONFIG_PREBOOT
 330
 331static uchar kbd_magic_prefix[] = "key_magic";
 332static uchar kbd_command_prefix[] = "key_cmd";
 333
 334static uchar *key_match (uchar * kbd_str)
 335{
 336        uchar magic[sizeof (kbd_magic_prefix) + 1];
 337        uchar cmd_name[sizeof (kbd_command_prefix) + 1];
 338        uchar *str, *suffix;
 339        uchar *kbd_magic_keys;
 340        char *cmd;
 341
 342        /*
 343         * The following string defines the characters that can pe appended
 344         * to "key_magic" to form the names of environment variables that
 345         * hold "magic" key codes, i. e. such key codes that can cause
 346         * pre-boot actions. If the string is empty (""), then only
 347         * "key_magic" is checked (old behaviour); the string "125" causes
 348         * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
 349         */
 350        if ((kbd_magic_keys = (uchar *)getenv ("magic_keys")) != NULL) {
 351                /* loop over all magic keys;
 352                 * use '\0' suffix in case of empty string
 353                 */
 354                for (suffix = kbd_magic_keys;
 355                     *suffix || suffix == kbd_magic_keys;
 356                     ++suffix) {
 357                        sprintf ((char *)magic, "%s%c", kbd_magic_prefix, *suffix);
 358
 359#if 0
 360                        printf ("### Check magic \"%s\"\n", magic);
 361#endif
 362
 363                        if ((str = (uchar *)getenv ((char *)magic)) != 0) {
 364
 365#if 0
 366                                printf ("### Compare \"%s\" \"%s\"\n",
 367                                        kbd_str, str);
 368#endif
 369                                if (strcmp ((char *)kbd_str, (char *)str) == 0) {
 370                                        sprintf ((char *)cmd_name, "%s%c",
 371                                                 kbd_command_prefix,
 372                                                 *suffix);
 373
 374                                        if ((cmd = getenv ((char *)cmd_name)) != 0) {
 375#if 0
 376                                                printf ("### Set PREBOOT to $(%s): \"%s\"\n",
 377                                                        cmd_name, cmd);
 378#endif
 379                                                return ((uchar *)cmd);
 380                                        }
 381                                }
 382                        }
 383                }
 384        }
 385#if 0
 386        printf ("### Delete PREBOOT\n");
 387#endif
 388        *kbd_str = '\0';
 389        return (NULL);
 390}
 391#endif  /* CONFIG_PREBOOT */
 392
 393/* Read Keyboard status */
 394int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 395{
 396        uchar kbd_data[KEYBD_DATALEN];
 397        uchar keybd_env[2 * KEYBD_DATALEN + 1];
 398        int i;
 399
 400        i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
 401
 402        /* Read keys */
 403        i2c_read (CONFIG_SYS_I2C_KEY_ADDR, 0, 0, kbd_data, KEYBD_DATALEN);
 404
 405        puts ("Keys:");
 406        for (i = 0; i < KEYBD_DATALEN; ++i) {
 407                sprintf ((char *)(keybd_env + i + i), "%02X", kbd_data[i]);
 408                printf (" %02x", kbd_data[i]);
 409        }
 410        putc ('\n');
 411        setenv ("keybd", (char *)keybd_env);
 412        return 0;
 413}
 414
 415U_BOOT_CMD(
 416        kbd,    1,      1,      do_kbd,
 417        "read keyboard status",
 418        ""
 419);
 420