uboot/board/keymile/km_arm/km_arm.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009
   3 * Marvell Semiconductor <www.marvell.com>
   4 * Prafulla Wadaskar <prafulla@marvell.com>
   5 *
   6 * (C) Copyright 2009
   7 * Stefan Roese, DENX Software Engineering, sr@denx.de.
   8 *
   9 * (C) Copyright 2010
  10 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  11 *
  12 * See file CREDITS for list of people who contributed to this
  13 * project.
  14 *
  15 * This program is free software; you can redistribute it and/or
  16 * modify it under the terms of the GNU General Public License as
  17 * published by the Free Software Foundation; either version 2 of
  18 * the License, or (at your option) any later version.
  19 *
  20 * This program is distributed in the hope that it will be useful,
  21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23 * GNU General Public License for more details.
  24 *
  25 * You should have received a copy of the GNU General Public License
  26 * along with this program; if not, write to the Free Software
  27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  28 * MA 02110-1301 USA
  29 */
  30
  31#include <common.h>
  32#include <i2c.h>
  33#include <nand.h>
  34#include <netdev.h>
  35#include <miiphy.h>
  36#include <asm/io.h>
  37#include <asm/arch/cpu.h>
  38#include <asm/arch/kirkwood.h>
  39#include <asm/arch/mpp.h>
  40
  41#include "../common/common.h"
  42
  43DECLARE_GLOBAL_DATA_PTR;
  44
  45/*
  46 * BOCO FPGA definitions
  47 */
  48#define BOCO            0x10
  49#define REG_CTRL_H              0x02
  50#define MASK_WRL_UNITRUN        0x01
  51#define MASK_RBX_PGY_PRESENT    0x40
  52#define REG_IRQ_CIRQ2           0x2d
  53#define MASK_RBI_DEFECT_16      0x01
  54
  55/* Multi-Purpose Pins Functionality configuration */
  56u32 kwmpp_config[] = {
  57        MPP0_NF_IO2,
  58        MPP1_NF_IO3,
  59        MPP2_NF_IO4,
  60        MPP3_NF_IO5,
  61        MPP4_NF_IO6,
  62        MPP5_NF_IO7,
  63        MPP6_SYSRST_OUTn,
  64        MPP7_PEX_RST_OUTn,
  65#if defined(CONFIG_SOFT_I2C)
  66        MPP8_GPIO,              /* SDA */
  67        MPP9_GPIO,              /* SCL */
  68#endif
  69#if defined(CONFIG_HARD_I2C)
  70        MPP8_TW_SDA,
  71        MPP9_TW_SCK,
  72#endif
  73        MPP10_UART0_TXD,
  74        MPP11_UART0_RXD,
  75        MPP12_GPO,              /* Reserved */
  76        MPP13_UART1_TXD,
  77        MPP14_UART1_RXD,
  78        MPP15_GPIO,             /* Not used */
  79        MPP16_GPIO,             /* Not used */
  80        MPP17_GPIO,             /* Reserved */
  81        MPP18_NF_IO0,
  82        MPP19_NF_IO1,
  83        MPP20_GPIO,
  84        MPP21_GPIO,
  85        MPP22_GPIO,
  86        MPP23_GPIO,
  87        MPP24_GPIO,
  88        MPP25_GPIO,
  89        MPP26_GPIO,
  90        MPP27_GPIO,
  91        MPP28_GPIO,
  92        MPP29_GPIO,
  93        MPP30_GPIO,
  94        MPP31_GPIO,
  95        MPP32_GPIO,
  96        MPP33_GPIO,
  97        MPP34_GPIO,             /* CDL1 (input) */
  98        MPP35_GPIO,             /* CDL2 (input) */
  99        MPP36_GPIO,             /* MAIN_IRQ (input) */
 100        MPP37_GPIO,             /* BOARD_LED */
 101        MPP38_GPIO,             /* Piggy3 LED[1] */
 102        MPP39_GPIO,             /* Piggy3 LED[2] */
 103        MPP40_GPIO,             /* Piggy3 LED[3] */
 104        MPP41_GPIO,             /* Piggy3 LED[4] */
 105        MPP42_GPIO,             /* Piggy3 LED[5] */
 106        MPP43_GPIO,             /* Piggy3 LED[6] */
 107        MPP44_GPIO,             /* Piggy3 LED[7], BIST_EN_L */
 108        MPP45_GPIO,             /* Piggy3 LED[8] */
 109        MPP46_GPIO,             /* Reserved */
 110        MPP47_GPIO,             /* Reserved */
 111        MPP48_GPIO,             /* Reserved */
 112        MPP49_GPIO,             /* SW_INTOUTn */
 113        0
 114};
 115
 116#if defined(CONFIG_MGCOGE3UN)
 117/*
 118 * Wait for startup OK from mgcoge3ne
 119 */
 120int startup_allowed(void)
 121{
 122        unsigned char buf;
 123
 124        /*
 125         * Read CIRQ16 bit (bit 0)
 126         */
 127        if (i2c_read(BOCO, REG_IRQ_CIRQ2, 1, &buf, 1) != 0)
 128                printf("%s: Error reading Boco\n", __func__);
 129        else
 130                if ((buf & MASK_RBI_DEFECT_16) == MASK_RBI_DEFECT_16)
 131                        return 1;
 132        return 0;
 133}
 134#endif
 135
 136#if (defined(CONFIG_MGCOGE3UN)|defined(CONFIG_PORTL2))
 137/*
 138 * These two boards have always ethernet present. Its connected to the mv
 139 * switch.
 140 */
 141int ethernet_present(void)
 142{
 143        return 1;
 144}
 145#else
 146int ethernet_present(void)
 147{
 148        uchar   buf;
 149        int     ret = 0;
 150
 151        if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
 152                printf("%s: Error reading Boco\n", __func__);
 153                return -1;
 154        }
 155        if ((buf & MASK_RBX_PGY_PRESENT) == MASK_RBX_PGY_PRESENT)
 156                ret = 1;
 157
 158        return ret;
 159}
 160#endif
 161
 162int initialize_unit_leds(void)
 163{
 164        /*
 165         * Init the unit LEDs per default they all are
 166         * ok apart from bootstat
 167         */
 168        uchar buf;
 169
 170        if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
 171                printf("%s: Error reading Boco\n", __func__);
 172                return -1;
 173        }
 174        buf |= MASK_WRL_UNITRUN;
 175        if (i2c_write(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
 176                printf("%s: Error writing Boco\n", __func__);
 177                return -1;
 178        }
 179        return 0;
 180}
 181
 182#if defined(CONFIG_BOOTCOUNT_LIMIT)
 183void set_bootcount_addr(void)
 184{
 185        uchar buf[32];
 186        unsigned int bootcountaddr;
 187        bootcountaddr = gd->ram_size - BOOTCOUNT_ADDR;
 188        sprintf((char *)buf, "0x%x", bootcountaddr);
 189        setenv("bootcountaddr", (char *)buf);
 190}
 191#endif
 192
 193int misc_init_r(void)
 194{
 195        char *str;
 196        int mach_type;
 197
 198        str = getenv("mach_type");
 199        if (str != NULL) {
 200                mach_type = simple_strtoul(str, NULL, 10);
 201                printf("Overwriting MACH_TYPE with %d!!!\n", mach_type);
 202                gd->bd->bi_arch_number = mach_type;
 203        }
 204#if defined(CONFIG_MGCOGE3UN)
 205        char *wait_for_ne;
 206        wait_for_ne = getenv("waitforne");
 207        if (wait_for_ne != NULL) {
 208                if (strcmp(wait_for_ne, "true") == 0) {
 209                        int cnt = 0;
 210                        int abort = 0;
 211                        puts("NE go: ");
 212                        while (startup_allowed() == 0) {
 213                                if (tstc()) {
 214                                        (void) getc(); /* consume input */
 215                                        abort = 1;
 216                                        break;
 217                                }
 218                                udelay(200000);
 219                                cnt++;
 220                                if (cnt == 5)
 221                                        puts("wait\b\b\b\b");
 222                                if (cnt == 10) {
 223                                        cnt = 0;
 224                                        puts("    \b\b\b\b");
 225                                }
 226                        }
 227                        if (abort == 1)
 228                                printf("\nAbort waiting for ne\n");
 229                        else
 230                                puts("OK\n");
 231                }
 232        }
 233#endif
 234
 235        initialize_unit_leds();
 236        set_km_env();
 237#if defined(CONFIG_BOOTCOUNT_LIMIT)
 238        set_bootcount_addr();
 239#endif
 240        return 0;
 241}
 242
 243int board_early_init_f(void)
 244{
 245        u32 tmp;
 246
 247        kirkwood_mpp_conf(kwmpp_config);
 248
 249        /*
 250         * The FLASH_GPIO_PIN switches between using a
 251         * NAND or a SPI FLASH. Set this pin on start
 252         * to NAND mode.
 253         */
 254        tmp = readl(KW_GPIO0_BASE);
 255        writel(tmp | FLASH_GPIO_PIN , KW_GPIO0_BASE);
 256        tmp = readl(KW_GPIO0_BASE + 4);
 257        writel(tmp & (~FLASH_GPIO_PIN) , KW_GPIO0_BASE + 4);
 258
 259#if defined(CONFIG_SOFT_I2C)
 260        /* init the GPIO for I2C Bitbang driver */
 261        kw_gpio_set_valid(KM_KIRKWOOD_SDA_PIN, 1);
 262        kw_gpio_set_valid(KM_KIRKWOOD_SCL_PIN, 1);
 263        kw_gpio_direction_output(KM_KIRKWOOD_SDA_PIN, 0);
 264        kw_gpio_direction_output(KM_KIRKWOOD_SCL_PIN, 0);
 265#endif
 266#if defined(CONFIG_SYS_EEPROM_WREN)
 267        kw_gpio_set_valid(KM_KIRKWOOD_ENV_WP, 38);
 268        kw_gpio_direction_output(KM_KIRKWOOD_ENV_WP, 1);
 269#endif
 270#if defined(CONFIG_KM_RECONFIG_XLX)
 271        /* trigger the reconfiguration of the xilinx fpga */
 272        kw_gpio_set_valid(KM_XLX_PROGRAM_B_PIN, 1);
 273        kw_gpio_direction_output(KM_XLX_PROGRAM_B_PIN, 0);
 274        kw_gpio_direction_input(KM_XLX_PROGRAM_B_PIN);
 275#endif
 276        return 0;
 277}
 278
 279int board_init(void)
 280{
 281        /* address of boot parameters */
 282        gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
 283
 284        return 0;
 285}
 286
 287#if defined(CONFIG_CMD_SF)
 288int do_spi_toggle(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 289{
 290        u32 tmp;
 291        if (argc < 2)
 292                return cmd_usage(cmdtp);
 293
 294        if ((strcmp(argv[1], "off") == 0)) {
 295                printf("SPI FLASH disabled, NAND enabled\n");
 296                /* Multi-Purpose Pins Functionality configuration */
 297                kwmpp_config[0] = MPP0_NF_IO2;
 298                kwmpp_config[1] = MPP1_NF_IO3;
 299                kwmpp_config[2] = MPP2_NF_IO4;
 300                kwmpp_config[3] = MPP3_NF_IO5;
 301
 302                kirkwood_mpp_conf(kwmpp_config);
 303                tmp = readl(KW_GPIO0_BASE);
 304                writel(tmp | FLASH_GPIO_PIN , KW_GPIO0_BASE);
 305        } else if ((strcmp(argv[1], "on") == 0)) {
 306                printf("SPI FLASH enabled, NAND disabled\n");
 307                /* Multi-Purpose Pins Functionality configuration */
 308                kwmpp_config[0] = MPP0_SPI_SCn;
 309                kwmpp_config[1] = MPP1_SPI_MOSI;
 310                kwmpp_config[2] = MPP2_SPI_SCK;
 311                kwmpp_config[3] = MPP3_SPI_MISO;
 312
 313                kirkwood_mpp_conf(kwmpp_config);
 314                tmp = readl(KW_GPIO0_BASE);
 315                writel(tmp & (~FLASH_GPIO_PIN) , KW_GPIO0_BASE);
 316        } else {
 317                return cmd_usage(cmdtp);
 318        }
 319
 320        return 0;
 321}
 322
 323U_BOOT_CMD(
 324        spitoggle,      2,      0,      do_spi_toggle,
 325        "En-/disable SPI FLASH access",
 326        "<on|off> - Enable (on) or disable (off) SPI FLASH access\n"
 327        );
 328#endif
 329
 330int dram_init(void)
 331{
 332        /* dram_init must store complete ramsize in gd->ram_size */
 333        /* Fix this */
 334        gd->ram_size = get_ram_size((void *)kw_sdram_bar(0),
 335                                kw_sdram_bs(0));
 336        return 0;
 337}
 338
 339void dram_init_banksize(void)
 340{
 341        int i;
 342
 343        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 344                gd->bd->bi_dram[i].start = kw_sdram_bar(i);
 345                gd->bd->bi_dram[i].size = get_ram_size((long *)kw_sdram_bar(i),
 346                                                       kw_sdram_bs(i));
 347        }
 348}
 349
 350#if (defined(CONFIG_MGCOGE3UN)|defined(CONFIG_PORTL2))
 351
 352#define PHY_LED_SEL     0x18
 353#define PHY_LED0_LINK   (0x5)
 354#define PHY_LED1_ACT    (0x8<<4)
 355#define PHY_LED2_INT    (0xe<<8)
 356#define PHY_SPEC_CTRL   0x1c
 357#define PHY_RGMII_CLK_STABLE    (0x1<<10)
 358#define PHY_CLSA        (0x1<<1)
 359
 360/* Configure and enable MV88E3018 PHY */
 361void reset_phy(void)
 362{
 363        char *name = "egiga0";
 364        unsigned short reg;
 365
 366        if (miiphy_set_current_dev(name))
 367                return;
 368
 369        /* RGMII clk transition on data stable */
 370        if (miiphy_read(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL, &reg) != 0)
 371                printf("Error reading PHY spec ctrl reg\n");
 372        if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL,
 373                reg | PHY_RGMII_CLK_STABLE | PHY_CLSA) != 0)
 374                printf("Error writing PHY spec ctrl reg\n");
 375
 376        /* leds setup */
 377        if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_LED_SEL,
 378                PHY_LED0_LINK | PHY_LED1_ACT | PHY_LED2_INT) != 0)
 379                printf("Error writing PHY LED reg\n");
 380
 381        /* reset the phy */
 382        miiphy_reset(name, CONFIG_PHY_BASE_ADR);
 383}
 384#else
 385/* Configure and enable MV88E1118 PHY on the piggy*/
 386void reset_phy(void)
 387{
 388        char *name = "egiga0";
 389
 390        if (miiphy_set_current_dev(name))
 391                return;
 392
 393        /* reset the phy */
 394        miiphy_reset(name, CONFIG_PHY_BASE_ADR);
 395}
 396#endif
 397
 398
 399#if defined(CONFIG_HUSH_INIT_VAR)
 400int hush_init_var(void)
 401{
 402        ivm_read_eeprom();
 403        return 0;
 404}
 405#endif
 406
 407#if defined(CONFIG_BOOTCOUNT_LIMIT)
 408const ulong patterns[]      = { 0x00000000,
 409                                0xFFFFFFFF,
 410                                0xFF00FF00,
 411                                0x0F0F0F0F,
 412                                0xF0F0F0F0};
 413const ulong NBR_OF_PATTERNS = sizeof(patterns)/sizeof(*patterns);
 414const ulong OFFS_PATTERN    = 3;
 415const ulong REPEAT_PATTERN  = 1000;
 416
 417void bootcount_store(ulong a)
 418{
 419        volatile ulong *save_addr;
 420        volatile ulong size = 0;
 421        int i;
 422        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 423                size += gd->bd->bi_dram[i].size;
 424        }
 425        save_addr = (ulong*)(size - BOOTCOUNT_ADDR);
 426        writel(a, save_addr);
 427        writel(BOOTCOUNT_MAGIC, &save_addr[1]);
 428
 429        for (i = 0; i < REPEAT_PATTERN; i++)
 430                writel(patterns[i % NBR_OF_PATTERNS],
 431                        &save_addr[i+OFFS_PATTERN]);
 432
 433}
 434
 435ulong bootcount_load(void)
 436{
 437        volatile ulong *save_addr;
 438        volatile ulong size = 0;
 439        ulong counter = 0;
 440        int i, tmp;
 441
 442        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 443                size += gd->bd->bi_dram[i].size;
 444        }
 445        save_addr = (ulong*)(size - BOOTCOUNT_ADDR);
 446
 447        counter = readl(&save_addr[0]);
 448
 449        /* Is the counter reliable, check in the big pattern for bit errors */
 450        for (i = 0; (i < REPEAT_PATTERN) && (counter != 0); i++) {
 451                tmp = readl(&save_addr[i+OFFS_PATTERN]);
 452                if (tmp != patterns[i % NBR_OF_PATTERNS])
 453                        counter = 0;
 454        }
 455        return counter;
 456}
 457#endif
 458
 459#if defined(CONFIG_SOFT_I2C)
 460void set_sda(int state)
 461{
 462        I2C_ACTIVE;
 463        I2C_SDA(state);
 464}
 465
 466void set_scl(int state)
 467{
 468        I2C_SCL(state);
 469}
 470
 471int get_sda(void)
 472{
 473        I2C_TRISTATE;
 474        return I2C_READ;
 475}
 476
 477int get_scl(void)
 478{
 479        return kw_gpio_get_value(KM_KIRKWOOD_SCL_PIN) ? 1 : 0;
 480}
 481#endif
 482
 483#if defined(CONFIG_POST)
 484
 485#define KM_POST_EN_L    44
 486#define POST_WORD_OFF   8
 487
 488int post_hotkeys_pressed(void)
 489{
 490        return !kw_gpio_get_value(KM_POST_EN_L);
 491}
 492
 493ulong post_word_load(void)
 494{
 495        volatile void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
 496        return in_le32(addr);
 497
 498}
 499void post_word_store(ulong value)
 500{
 501        volatile void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
 502        out_le32(addr, value);
 503}
 504
 505int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
 506{
 507        *vstart = CONFIG_SYS_SDRAM_BASE;
 508
 509        /* we go up to relocation plus a 1 MB margin */
 510        *size = CONFIG_SYS_TEXT_BASE - (1<<20);
 511
 512        return 0;
 513}
 514#endif
 515
 516#if defined(CONFIG_SYS_EEPROM_WREN)
 517int eeprom_write_enable(unsigned dev_addr, int state)
 518{
 519        kw_gpio_set_value(KM_KIRKWOOD_ENV_WP, !state);
 520
 521        return !kw_gpio_get_value(KM_KIRKWOOD_ENV_WP);
 522}
 523#endif
 524