uboot/board/a3m071/a3m071.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 2006
   9 * MicroSys GmbH
  10 *
  11 * Copyright 2012 Stefan Roese <sr@denx.de>
  12 *
  13 * See file CREDITS for list of people who contributed to this
  14 * project.
  15 *
  16 * This program is free software; you can redistribute it and/or
  17 * modify it under the terms of the GNU General Public License as
  18 * published by the Free Software Foundation; either version 2 of
  19 * the License, or (at your option) any later version.
  20 */
  21
  22#include <common.h>
  23#include <command.h>
  24#include <mpc5xxx.h>
  25#include <pci.h>
  26#include <miiphy.h>
  27#include <linux/compiler.h>
  28#include <asm/processor.h>
  29#include <asm/io.h>
  30
  31#ifdef CONFIG_A4M2K
  32#include "is46r16320d.h"
  33#else
  34#include "mt46v16m16-75.h"
  35#endif
  36
  37DECLARE_GLOBAL_DATA_PTR;
  38
  39#if !defined(CONFIG_SYS_RAMBOOT) && \
  40        (defined(CONFIG_SPL) && defined(CONFIG_SPL_BUILD))
  41static void sdram_start(int hi_addr)
  42{
  43        long hi_addr_bit = hi_addr ? 0x01000000 : 0;
  44        long control = SDRAM_CONTROL | hi_addr_bit;
  45
  46        /* unlock mode register */
  47        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000000);
  48
  49        /* precharge all banks */
  50        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000002);
  51
  52#ifdef SDRAM_DDR
  53        /* set mode register: extended mode */
  54        out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_EMODE);
  55
  56        /* set mode register: reset DLL */
  57        out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_MODE | 0x04000000);
  58#endif
  59
  60        /* precharge all banks */
  61        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000002);
  62
  63        /* auto refresh */
  64        out_be32((void *)MPC5XXX_SDRAM_CTRL, control | 0x80000004);
  65
  66        /* set mode register */
  67        out_be32((void *)MPC5XXX_SDRAM_MODE, SDRAM_MODE);
  68
  69        /* normal operation */
  70        out_be32((void *)MPC5XXX_SDRAM_CTRL, control);
  71
  72        /*
  73         * Wait a short while for the DLL to lock before accessing
  74         * the SDRAM
  75         */
  76        udelay(100);
  77}
  78#endif
  79
  80/*
  81 * ATTENTION: Although partially referenced initdram does NOT make real use
  82 * use of CONFIG_SYS_SDRAM_BASE. The code does not work if
  83 * CONFIG_SYS_SDRAM_BASE is something else than 0x00000000.
  84 */
  85phys_size_t initdram(int board_type)
  86{
  87        ulong dramsize = 0;
  88        ulong dramsize2 = 0;
  89        uint svr, pvr;
  90#if !defined(CONFIG_SYS_RAMBOOT) && \
  91        (defined(CONFIG_SPL) && defined(CONFIG_SPL_BUILD))
  92        ulong test1, test2;
  93
  94        /* setup SDRAM chip selects */
  95        out_be32((void *)MPC5XXX_SDRAM_CS0CFG, 0x0000001e);     /* 2GB at 0x0 */
  96        out_be32((void *)MPC5XXX_SDRAM_CS1CFG, 0x80000000);     /* disabled */
  97
  98        /* setup config registers */
  99        out_be32((void *)MPC5XXX_SDRAM_CONFIG1, SDRAM_CONFIG1);
 100        out_be32((void *)MPC5XXX_SDRAM_CONFIG2, SDRAM_CONFIG2);
 101
 102#ifdef SDRAM_DDR
 103        /* set tap delay */
 104        out_be32((void *)MPC5XXX_CDM_PORCFG, SDRAM_TAPDELAY);
 105#endif
 106
 107        /* find RAM size using SDRAM CS0 only */
 108        sdram_start(0);
 109        test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
 110        sdram_start(1);
 111        test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
 112        if (test1 > test2) {
 113                sdram_start(0);
 114                dramsize = test1;
 115        } else {
 116                dramsize = test2;
 117        }
 118
 119        /* memory smaller than 1MB is impossible */
 120        if (dramsize < (1 << 20))
 121                dramsize = 0;
 122
 123        /* set SDRAM CS0 size according to the amount of RAM found */
 124        if (dramsize > 0) {
 125                out_be32((void *)MPC5XXX_SDRAM_CS0CFG,
 126                         0x13 + __builtin_ffs(dramsize >> 20) - 1);
 127        } else {
 128                out_be32((void *)MPC5XXX_SDRAM_CS0CFG, 0);      /* disabled */
 129        }
 130#else /* CONFIG_SYS_RAMBOOT */
 131
 132        /* retrieve size of memory connected to SDRAM CS0 */
 133        dramsize = in_be32((void *)MPC5XXX_SDRAM_CS0CFG) & 0xFF;
 134        if (dramsize >= 0x13)
 135                dramsize = (1 << (dramsize - 0x13)) << 20;
 136        else
 137                dramsize = 0;
 138
 139        /* retrieve size of memory connected to SDRAM CS1 */
 140        dramsize2 = in_be32((void *)MPC5XXX_SDRAM_CS1CFG) & 0xFF;
 141        if (dramsize2 >= 0x13)
 142                dramsize2 = (1 << (dramsize2 - 0x13)) << 20;
 143        else
 144                dramsize2 = 0;
 145
 146#endif /* CONFIG_SYS_RAMBOOT */
 147
 148        /*
 149         * On MPC5200B we need to set the special configuration delay in the
 150         * DDR controller. Please refer to Freescale's AN3221 "MPC5200B SDRAM
 151         * Initialization and Configuration", 3.3.1 SDelay--MBAR + 0x0190:
 152         *
 153         * "The SDelay should be written to a value of 0x00000004. It is
 154         * required to account for changes caused by normal wafer processing
 155         * parameters."
 156         */
 157        svr = get_svr();
 158        pvr = get_pvr();
 159        if ((SVR_MJREV(svr) >= 2) && (PVR_MAJ(pvr) == 1) && (PVR_MIN(pvr) == 4))
 160                out_be32((void *)MPC5XXX_SDRAM_SDELAY, 0x04);
 161
 162        return dramsize + dramsize2;
 163}
 164
 165static void get_revisions(int *failsavelevel, int *digiboardversion,
 166        int *fpgaversion)
 167{
 168        struct mpc5xxx_gpt_0_7 *gpt = (struct mpc5xxx_gpt_0_7 *)MPC5XXX_GPT;
 169        u8 val;
 170
 171        /* read digitalboard-version from TMR[2..4] */
 172        val = 0;
 173        val |= (gpt->gpt2.sr & (1 << (31 - 23))) ? (1) : 0;
 174        val |= (gpt->gpt3.sr & (1 << (31 - 23))) ? (1 << 1) : 0;
 175        val |= (gpt->gpt4.sr & (1 << (31 - 23))) ? (1 << 2) : 0;
 176        *digiboardversion = val;
 177
 178        /*
 179         * A4M2K only supports digiboardversion. No failsavelevel and
 180         * fpgaversion here.
 181         */
 182#if !defined(CONFIG_A4M2K)
 183        /*
 184         * Figure out failsavelevel
 185         * see ticket dsvk#59
 186         */
 187        *failsavelevel = 0;     /* 0=failsave, 1=board ok, 2=fpga ok */
 188
 189        if (*digiboardversion == 0) {
 190                *failsavelevel = 1;     /* digiboard-version ok */
 191
 192                /* read fpga-version from TMR[5..7] */
 193                val = 0;
 194                val |= (gpt->gpt5.sr & (1 << (31 - 23))) ? (1) : 0;
 195                val |= (gpt->gpt6.sr & (1 << (31 - 23))) ? (1 << 1) : 0;
 196                val |= (gpt->gpt7.sr & (1 << (31 - 23))) ? (1 << 2) : 0;
 197                *fpgaversion = val;
 198
 199                if (*fpgaversion == 1)
 200                        *failsavelevel = 2;     /* fpga-version ok */
 201        }
 202#endif
 203}
 204
 205/*
 206 * This function is called from the SPL U-Boot version for
 207 * early init stuff, that needs to be done for OS (e.g. Linux)
 208 * booting. Doing it later in the real U-Boot would not work
 209 * in case that the SPL U-Boot boots Linux directly.
 210 */
 211void spl_board_init(void)
 212{
 213        struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio *)MPC5XXX_GPIO;
 214        struct mpc5xxx_mmap_ctl *mm =
 215                (struct mpc5xxx_mmap_ctl *)CONFIG_SYS_MBAR;
 216
 217#if defined(CONFIG_A4M2K)
 218        /* enable CS3 and CS5 (FPGA) */
 219        setbits_be32(&mm->ipbi_ws_ctrl, (1 << 19) | (1 << 21));
 220#else
 221        int digiboardversion;
 222        int failsavelevel;
 223        int fpgaversion;
 224        u32 val;
 225
 226        get_revisions(&failsavelevel, &digiboardversion, &fpgaversion);
 227
 228        val = in_be32(&mm->ipbi_ws_ctrl);
 229
 230        /* first clear bits 19..21 (CS3...5) */
 231        val &= ~((1 << 19) | (1 << 20) | (1 << 21));
 232        if (failsavelevel == 2) {
 233                /* FPGA ok */
 234                val |= (1 << 19) | (1 << 21);
 235        }
 236
 237        if (failsavelevel >= 1) {
 238                /* at least digiboard-version ok */
 239                val |= (1 << 20);
 240        }
 241
 242        /* And write new value back to register */
 243        out_be32(&mm->ipbi_ws_ctrl, val);
 244#endif
 245
 246        /*
 247         * No need to change the pin multiplexing (MPC5XXX_GPS_PORT_CONFIG)
 248         * as all 3 config versions (failsave level) have the same setup.
 249         */
 250
 251        /*
 252         * Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see
 253         * ticket #60
 254         *
 255         * MPC5XXX_WU_GPIO_DIR direction is already 0 (INPUT)
 256         * set bit 0(msb) to 1
 257         */
 258        setbits_be32((void *)MPC5XXX_WU_GPIO_ENABLE, CONFIG_WDOG_GPIO_PIN);
 259
 260#if defined(CONFIG_A4M2K)
 261        /* Setup USB[x] as MPCDiag[0..3] GPIO outputs */
 262
 263        /* set USB0,6,7,8 (MPCDiag[0..3]) direction to output */
 264        gpio->simple_ddr |= 1 << (31 - 15);
 265        gpio->simple_ddr |= 1 << (31 - 14);
 266        gpio->simple_ddr |= 1 << (31 - 13);
 267        gpio->simple_ddr |= 1 << (31 - 12);
 268
 269        /* enable USB0,6,7,8 (MPCDiag[0..3]) as GPIO */
 270        gpio->simple_gpioe |= 1 << (31 - 15);
 271        gpio->simple_gpioe |= 1 << (31 - 14);
 272        gpio->simple_gpioe |= 1 << (31 - 13);
 273        gpio->simple_gpioe |= 1 << (31 - 12);
 274
 275        /* Setup PSC2[0..2] as STSLED[0..2] GPIO outputs */
 276
 277        /* set PSC2[0..2] (STSLED[0..2]) direction to output */
 278        gpio->simple_ddr |= 1 << (31 - 27);
 279        gpio->simple_ddr |= 1 << (31 - 26);
 280        gpio->simple_ddr |= 1 << (31 - 25);
 281
 282        /* enable PSC2[0..2] (STSLED[0..2]) as GPIO */
 283        gpio->simple_gpioe |= 1 << (31 - 27);
 284        gpio->simple_gpioe |= 1 << (31 - 26);
 285        gpio->simple_gpioe |= 1 << (31 - 25);
 286
 287        /* Setup PSC6[2] as MRST2 self reset GPIO output */
 288
 289        /* set PSC6[2]/IRDA_TX (MRST2) direction to output */
 290        gpio->simple_ddr |= 1 << (31 - 3);
 291
 292        /* set PSC6[2]/IRDA_TX (MRST2) output as open drain */
 293        gpio->simple_ode |= 1 << (31 - 3);
 294
 295        /* set PSC6[2]/IRDA_TX (MRST2) output as default high */
 296        gpio->simple_dvo |= 1 << (31 - 3);
 297
 298        /* enable PSC6[2]/IRDA_TX (MRST2) as GPIO */
 299        gpio->simple_gpioe |= 1 << (31 - 3);
 300
 301        /* Setup PSC6[3] as HARNSSCD harness code GPIO input */
 302
 303        /* set PSC6[3]/IR_USB_CLK (HARNSSCD) direction to input */
 304        gpio->simple_ddr |= 0 << (31 - 2);
 305
 306        /* enable PSC6[3]/IR_USB_CLK (HARNSSCD) as GPIO */
 307        gpio->simple_gpioe |= 1 << (31 - 2);
 308#else
 309        /* setup GPIOs for status-leds if needed - see ticket #57 */
 310        if (failsavelevel > 0) {
 311                /* digiboard-version is OK */
 312                /* LED is LOW ACTIVE - so deactivate by set output to 1 */
 313                gpio->simple_dvo |= 1 << (31 - 12);
 314                gpio->simple_dvo |= 1 << (31 - 13);
 315                /* set GPIO direction to output */
 316                gpio->simple_ddr |= 1 << (31 - 12);
 317                gpio->simple_ddr |= 1 << (31 - 13);
 318                /* open drain config is set to "normal output" at reset */
 319                /* gpio->simple_ode &=~ ( 1 << (31-12) ); */
 320                /* gpio->simple_ode &=~ ( 1 << (31-13) ); */
 321                /* enable as GPIO */
 322                gpio->simple_gpioe |= 1 << (31 - 12);
 323                gpio->simple_gpioe |= 1 << (31 - 13);
 324        }
 325
 326        /* setup fpga irq - see ticket #65 */
 327        if (failsavelevel > 1) {
 328                /*
 329                 * The main irq initialisation is done in interrupts.c
 330                 * mpc5xxx_init_irq
 331                 */
 332                struct mpc5xxx_intr *intr =
 333                    (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
 334
 335                setbits_be32(&intr->ctrl, 0x08C01801);
 336
 337                /*
 338                 * The MBAR+0x0524 Bit 21:23 CSe are ignored here due to the
 339                 * already cleared (intr_ctrl) MBAR+0x0510 ECLR[0] bit above
 340                 */
 341        }
 342#endif
 343}
 344
 345int checkboard(void)
 346{
 347        int digiboardversion;
 348        int failsavelevel;
 349        int fpgaversion;
 350
 351        get_revisions(&failsavelevel, &digiboardversion, &fpgaversion);
 352
 353#ifdef CONFIG_A4M2K
 354        puts("Board: A4M2K\n");
 355        printf("       digiboard IO version %u\n", digiboardversion);
 356#else
 357        puts("Board: A3M071\n");
 358        printf("Rev:   failsave level       %u\n", failsavelevel);
 359        printf("       digiboard IO version %u\n", digiboardversion);
 360        if (failsavelevel > 0)  /* only if fpga-version red */
 361                printf("       fpga IO version      %u\n", fpgaversion);
 362#endif
 363
 364        return 0;
 365}
 366
 367/* miscellaneous platform dependent initialisations */
 368int misc_init_r(void)
 369{
 370        /* adjust flash start and offset to detected values */
 371        gd->bd->bi_flashstart = flash_info[0].start[0];
 372        gd->bd->bi_flashoffset = 0;
 373
 374        /* adjust mapping */
 375        out_be32((void *)MPC5XXX_BOOTCS_START,
 376                 START_REG(gd->bd->bi_flashstart));
 377        out_be32((void *)MPC5XXX_CS0_START, START_REG(gd->bd->bi_flashstart));
 378        out_be32((void *)MPC5XXX_BOOTCS_STOP,
 379                 STOP_REG(gd->bd->bi_flashstart, gd->bd->bi_flashsize));
 380        out_be32((void *)MPC5XXX_CS0_STOP,
 381                 STOP_REG(gd->bd->bi_flashstart, gd->bd->bi_flashsize));
 382
 383        return 0;
 384}
 385
 386#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
 387void ft_board_setup(void *blob, bd_t * bd)
 388{
 389        ft_cpu_setup(blob, bd);
 390}
 391#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */
 392
 393#ifdef CONFIG_SPL_OS_BOOT
 394/*
 395 * A3M071 specific implementation of spl_start_uboot()
 396 *
 397 * RETURN
 398 * 0 if booting into OS is selected (default)
 399 * 1 if booting into U-Boot is selected
 400 */
 401int spl_start_uboot(void)
 402{
 403        char s[8];
 404
 405        env_init();
 406        getenv_f("boot_os", s, sizeof(s));
 407        if ((s != NULL) && (strcmp(s, "yes") == 0))
 408                return 0;
 409
 410        return 1;
 411}
 412#endif
 413
 414#if defined(CONFIG_HW_WATCHDOG)
 415static int watchdog_toggle;
 416
 417void hw_watchdog_reset(void)
 418{
 419        int val;
 420
 421        /*
 422         * Check if watchdog is enabled via user command
 423         */
 424        if ((gd->flags & GD_FLG_RELOC) && watchdog_toggle) {
 425                /* Set direction to output */
 426                setbits_be32((void *)MPC5XXX_WU_GPIO_DIR, CONFIG_WDOG_GPIO_PIN);
 427
 428                /*
 429                 * Toggle watchdog output
 430                 */
 431                val = (in_be32((void *)MPC5XXX_WU_GPIO_DATA_O) &
 432                       CONFIG_WDOG_GPIO_PIN);
 433                if (val) {
 434                        clrbits_be32((void *)MPC5XXX_WU_GPIO_DATA_O,
 435                                     CONFIG_WDOG_GPIO_PIN);
 436                } else {
 437                        setbits_be32((void *)MPC5XXX_WU_GPIO_DATA_O,
 438                                     CONFIG_WDOG_GPIO_PIN);
 439                }
 440        }
 441}
 442
 443int do_wdog_toggle(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 444{
 445        if (argc != 2)
 446                goto usage;
 447
 448        if (strncmp(argv[1], "on", 2) == 0)
 449                watchdog_toggle = 1;
 450        else if (strncmp(argv[1], "off", 3) == 0)
 451                watchdog_toggle = 0;
 452        else
 453                goto usage;
 454
 455        return 0;
 456usage:
 457        printf("Usage: wdogtoggle %s\n", cmdtp->usage);
 458        return 1;
 459}
 460
 461U_BOOT_CMD(
 462        wdogtoggle, CONFIG_SYS_MAXARGS, 2, do_wdog_toggle,
 463        "toggle GPIO pin to service watchdog",
 464        "[on/off] - Switch watchdog toggling via GPIO pin on/off"
 465);
 466#endif
 467