uboot/board/trab/trab.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2002
   3 * Gary Jennejohn, DENX Software Engineering, <garyj@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/* #define DEBUG */
  25
  26#include <common.h>
  27#include <netdev.h>
  28#include <malloc.h>
  29#include <asm/arch/s3c24x0_cpu.h>
  30#include <command.h>
  31
  32DECLARE_GLOBAL_DATA_PTR;
  33
  34#ifdef CONFIG_SYS_BRIGHTNESS
  35static void spi_init(void);
  36static void wait_transmit_done(void);
  37static void tsc2000_write(unsigned int page, unsigned int reg,
  38                                                  unsigned int data);
  39static void tsc2000_set_brightness(void);
  40#endif
  41#ifdef CONFIG_MODEM_SUPPORT
  42static int key_pressed(void);
  43extern void disable_putc(void);
  44extern int do_mdm_init; /* defined in common/main.c */
  45
  46/*
  47 * We need a delay of at least 500 us after turning on the VFD clock
  48 * before we can read any useful information for the CPLD controlling
  49 * the keyboard switches. Let's play safe and wait 5 ms. The problem
  50 * is that timers are not available yet, so we use a manually timed
  51 * loop.
  52 */
  53#define KBD_MDELAY      5000
  54static void udelay_no_timer (int usec)
  55{
  56        int i;
  57        int delay = usec * 3;
  58
  59        for (i = 0; i < delay; i ++) gd->bd->bi_arch_number = MACH_TYPE_TRAB;
  60}
  61#endif /* CONFIG_MODEM_SUPPORT */
  62
  63/*
  64 * Miscellaneous platform dependent initialisations
  65 */
  66
  67int board_init ()
  68{
  69#if defined(CONFIG_VFD)
  70        extern int vfd_init_clocks(void);
  71#endif
  72        struct s3c24x0_clock_power * const clk_power =
  73                                        s3c24x0_get_base_clock_power();
  74        struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
  75
  76        /* memory and cpu-speed are setup before relocation */
  77#ifdef CONFIG_TRAB_50MHZ
  78        /* change the clock to be 50 MHz 1:1:1 */
  79        /* MDIV:0x5c PDIV:4 SDIV:2 */
  80        clk_power->mpllcon = 0x5c042;
  81        clk_power->clkdivn = 0;
  82#else
  83        /* change the clock to be 133 MHz 1:2:4 */
  84        /* MDIV:0x7d PDIV:4 SDIV:1 */
  85        clk_power->mpllcon = 0x7d041;
  86        clk_power->clkdivn = 3;
  87#endif
  88
  89        /* set up the I/O ports */
  90        gpio->pacon = 0x3ffff;
  91        gpio->pbcon = 0xaaaaaaaa;
  92        gpio->pbup  = 0xffff;
  93        /* INPUT nCTS0 nRTS0 TXD[1] TXD[0] RXD[1] RXD[0]        */
  94        /*  00,    10,      10,      10,      10,      10,      10      */
  95        gpio->pfcon = (2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8) | (2<<10);
  96#ifdef CONFIG_HWFLOW
  97        /* do not pull up RXD0, RXD1, TXD0, TXD1, CTS0, RTS0 */
  98        gpio->pfup  = (1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4) | (1<<5);
  99#else
 100        /* do not pull up RXD0, RXD1, TXD0, TXD1 */
 101        gpio->pfup  = (1<<0) | (1<<1) | (1<<2) | (1<<3);
 102#endif
 103        gpio->pgcon = 0x0;
 104        gpio->pgup  = 0x0;
 105        gpio->opencr = 0x0;
 106
 107        /* suppress flicker of the VFDs */
 108        gpio->misccr = 0x40;
 109        gpio->pfcon |= (2<<12);
 110
 111        gd->bd->bi_arch_number = MACH_TYPE_TRAB;
 112
 113        /* adress of boot parameters */
 114        gd->bd->bi_boot_params = 0x0c000100;
 115
 116        /* Make sure both buzzers are turned off */
 117        gpio->pdcon |= 0x5400;
 118        gpio->pddat &= ~0xE0;
 119
 120#ifdef CONFIG_VFD
 121        vfd_init_clocks();
 122#endif /* CONFIG_VFD */
 123
 124#ifdef CONFIG_MODEM_SUPPORT
 125        udelay_no_timer (KBD_MDELAY);
 126
 127        if (key_pressed()) {
 128                disable_putc(); /* modem doesn't understand banner etc */
 129                do_mdm_init = 1;
 130        }
 131#endif  /* CONFIG_MODEM_SUPPORT */
 132
 133#ifdef CONFIG_DRIVER_S3C24X0_I2C
 134        /* Configure I/O ports PG5 und PG6 for I2C */
 135        gpio->pgcon = (gpio->pgcon & 0x003c00) | 0x003c00;
 136#endif /* CONFIG_DRIVER_S3C24X0_I2C */
 137
 138        return 0;
 139}
 140
 141int dram_init (void)
 142{
 143        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 144        gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
 145        return 0;
 146}
 147
 148/*-----------------------------------------------------------------------
 149 * Keyboard Controller
 150 */
 151
 152/* Maximum key number */
 153#define KEYBD_KEY_NUM           4
 154
 155#define KBD_DATA        (((*(volatile ulong *)0x04020000) >> 16) & 0xF)
 156
 157static char *key_match (ulong);
 158
 159int misc_init_r (void)
 160{
 161        ulong kbd_data = KBD_DATA;
 162        char *str;
 163        char keybd_env[KEYBD_KEY_NUM + 1];
 164        int i;
 165
 166#ifdef CONFIG_VERSION_VARIABLE
 167        {
 168                /* Set version variable. Please note, that this variable is
 169                 * also set in main_loop() later in the boot process. The
 170                 * version variable has to be set this early, because so it
 171                 * could be used in script files on an usb stick, which
 172                 * might be called during do_auto_update() */
 173                extern char version_string[];
 174
 175                setenv ("ver", version_string);
 176        }
 177#endif /* CONFIG_VERSION_VARIABLE */
 178
 179#ifdef CONFIG_AUTO_UPDATE
 180        {
 181                extern int do_auto_update(void);
 182                /* this has priority over all else */
 183                do_auto_update();
 184        }
 185#endif
 186
 187        for (i = 0; i < KEYBD_KEY_NUM; ++i) {
 188                keybd_env[i] = '0' + ((kbd_data >> i) & 1);
 189        }
 190        keybd_env[i] = '\0';
 191        debug ("** Setting keybd=\"%s\"\n", keybd_env);
 192        setenv ("keybd", keybd_env);
 193
 194        str = strdup (key_match (kbd_data));    /* decode keys */
 195
 196#ifdef CONFIG_PREBOOT   /* automatically configure "preboot" command on key match */
 197        debug ("** Setting preboot=\"%s\"\n", str);
 198        setenv ("preboot", str);        /* set or delete definition */
 199#endif /* CONFIG_PREBOOT */
 200        if (str != NULL) {
 201                free (str);
 202        }
 203
 204#ifdef CONFIG_SYS_BRIGHTNESS
 205        tsc2000_set_brightness();
 206#endif
 207        return (0);
 208}
 209
 210#ifdef CONFIG_PREBOOT
 211
 212static uchar kbd_magic_prefix[] = "key_magic";
 213static uchar kbd_command_prefix[] = "key_cmd";
 214
 215static int compare_magic (ulong kbd_data, char *str)
 216{
 217        uchar key_mask;
 218
 219        debug ("compare_magic: kbd: %04lx  str: \"%s\"\n",kbd_data,str);
 220        for (; *str; str++)
 221        {
 222                uchar c = *str - '1';
 223
 224                if (c >= KEYBD_KEY_NUM)         /* bad key number */
 225                        return -1;
 226
 227                key_mask = 1 << c;
 228
 229                if (!(kbd_data & key_mask)) {   /* key not pressed */
 230                        debug ( "compare_magic: "
 231                                "kbd: %04lx mask: %04lx - key not pressed\n",
 232                                kbd_data, key_mask );
 233                        return -1;
 234                }
 235
 236                kbd_data &= ~key_mask;
 237        }
 238
 239        if (kbd_data) {                         /* key(s) not released */
 240                debug ( "compare_magic: "
 241                        "kbd: %04lx - key(s) not released\n", kbd_data);
 242                return -1;
 243        }
 244
 245        return 0;
 246}
 247
 248/*-----------------------------------------------------------------------
 249 * Check if pressed key(s) match magic sequence,
 250 * and return the command string associated with that key(s).
 251 *
 252 * If no key press was decoded, NULL is returned.
 253 *
 254 * Note: the first character of the argument will be overwritten with
 255 * the "magic charcter code" of the decoded key(s), or '\0'.
 256 *
 257 *
 258 * Note: the string points to static environment data and must be
 259 * saved before you call any function that modifies the environment.
 260 */
 261static char *key_match (ulong kbd_data)
 262{
 263        char magic[sizeof (kbd_magic_prefix) + 1];
 264        char cmd_name[sizeof (kbd_command_prefix) + 1];
 265        char *suffix;
 266        char *kbd_magic_keys;
 267
 268        /*
 269         * The following string defines the characters that can pe appended
 270         * to "key_magic" to form the names of environment variables that
 271         * hold "magic" key codes, i. e. such key codes that can cause
 272         * pre-boot actions. If the string is empty (""), then only
 273         * "key_magic" is checked (old behaviour); the string "125" causes
 274         * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
 275         */
 276        if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
 277                kbd_magic_keys = "";
 278
 279        debug ("key_match: magic_keys=\"%s\"\n", kbd_magic_keys);
 280
 281        /* loop over all magic keys;
 282         * use '\0' suffix in case of empty string
 283         */
 284        for (suffix=kbd_magic_keys; *suffix || suffix==kbd_magic_keys; ++suffix)
 285        {
 286                sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
 287
 288                debug ("key_match: magic=\"%s\"\n",
 289                        getenv(magic) ? getenv(magic) : "<UNDEFINED>");
 290
 291                if (compare_magic(kbd_data, getenv(magic)) == 0)
 292                {
 293                        sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
 294                        debug ("key_match: cmdname %s=\"%s\"\n",
 295                                cmd_name,
 296                                getenv (cmd_name) ?
 297                                        getenv (cmd_name) :
 298                                        "<UNDEFINED>");
 299                        return (getenv (cmd_name));
 300                }
 301        }
 302        debug ("key_match: no match\n");
 303        return (NULL);
 304}
 305#endif                                                  /* CONFIG_PREBOOT */
 306
 307/* Read Keyboard status */
 308int do_kbd (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 309{
 310        ulong kbd_data = KBD_DATA;
 311        char keybd_env[KEYBD_KEY_NUM + 1];
 312        int i;
 313
 314        puts ("Keys:");
 315        for (i = 0; i < KEYBD_KEY_NUM; ++i) {
 316                keybd_env[i] = '0' + ((kbd_data >> i) & 1);
 317                printf (" %c", keybd_env[i]);
 318        }
 319        keybd_env[i] = '\0';
 320        putc ('\n');
 321        setenv ("keybd", keybd_env);
 322        return 0;
 323}
 324
 325U_BOOT_CMD(
 326        kbd,    1,      1,      do_kbd,
 327        "read keyboard status",
 328        ""
 329);
 330
 331#ifdef CONFIG_MODEM_SUPPORT
 332static int key_pressed(void)
 333{
 334        return (compare_magic(KBD_DATA, CONFIG_MODEM_KEY_MAGIC) == 0);
 335}
 336#endif  /* CONFIG_MODEM_SUPPORT */
 337
 338#ifdef CONFIG_SYS_BRIGHTNESS
 339
 340static inline void SET_CS_TOUCH(void)
 341{
 342        struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
 343
 344        gpio->pddat &= 0x5FF;
 345}
 346
 347static inline void CLR_CS_TOUCH(void)
 348{
 349        struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
 350
 351        gpio->pddat |= 0x200;
 352}
 353
 354static void spi_init(void)
 355{
 356        struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
 357        struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
 358        int i;
 359
 360        /* Configure I/O ports. */
 361        gpio->pdcon = (gpio->pdcon & 0xF3FFFF) | 0x040000;
 362        gpio->pgcon = (gpio->pgcon & 0x0F3FFF) | 0x008000;
 363        gpio->pgcon = (gpio->pgcon & 0x0CFFFF) | 0x020000;
 364        gpio->pgcon = (gpio->pgcon & 0x03FFFF) | 0x080000;
 365
 366        CLR_CS_TOUCH();
 367
 368        spi->ch[0].sppre = 0x1F; /* Baudrate ca. 514kHz */
 369        spi->ch[0].sppin = 0x01;  /* SPI-MOSI holds Level after last bit */
 370        spi->ch[0].spcon = 0x1A; /* Polling, Prescale, Master, CPOL=0, CPHA=1 */
 371
 372        /* Dummy byte ensures clock to be low. */
 373        for (i = 0; i < 10; i++) {
 374                spi->ch[0].sptdat = 0xFF;
 375        }
 376        wait_transmit_done();
 377}
 378
 379static void wait_transmit_done(void)
 380{
 381        struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
 382
 383        while (!(spi->ch[0].spsta & 0x01)) /* wait until transfer is done */
 384                ;
 385}
 386
 387static void tsc2000_write(unsigned int page, unsigned int reg,
 388                                                  unsigned int data)
 389{
 390        struct s3c24x0_spi * const spi = s3c24x0_get_base_spi();
 391        unsigned int command;
 392
 393        SET_CS_TOUCH();
 394        command = 0x0000;
 395        command |= (page << 11);
 396        command |= (reg << 5);
 397
 398        spi->ch[0].sptdat = (command & 0xFF00) >> 8;
 399        wait_transmit_done();
 400        spi->ch[0].sptdat = (command & 0x00FF);
 401        wait_transmit_done();
 402        spi->ch[0].sptdat = (data & 0xFF00) >> 8;
 403        wait_transmit_done();
 404        spi->ch[0].sptdat = (data & 0x00FF);
 405        wait_transmit_done();
 406
 407        CLR_CS_TOUCH();
 408}
 409
 410static void tsc2000_set_brightness(void)
 411{
 412        char tmp[10];
 413        int i, br;
 414
 415        spi_init();
 416        tsc2000_write(1, 2, 0x0); /* Power up DAC */
 417
 418        i = getenv_f("brightness", tmp, sizeof(tmp));
 419        br = (i > 0)
 420                ? (int) simple_strtoul (tmp, NULL, 10)
 421                : CONFIG_SYS_BRIGHTNESS;
 422
 423        tsc2000_write(0, 0xb, br & 0xff);
 424}
 425#endif
 426
 427#ifdef CONFIG_CMD_NET
 428int board_eth_init(bd_t *bis)
 429{
 430        int rc = 0;
 431#ifdef CONFIG_CS8900
 432        rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
 433#endif
 434        return rc;
 435}
 436#endif
 437