uboot/board/liebherr/lwmon5/lwmon5.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2007-2013
   3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <command.h>
  10#include <asm/ppc440.h>
  11#include <asm/processor.h>
  12#include <asm/ppc4xx-gpio.h>
  13#include <asm/io.h>
  14#include <post.h>
  15#include <flash.h>
  16#include <video.h>
  17#include <mtd/cfi_flash.h>
  18
  19DECLARE_GLOBAL_DATA_PTR;
  20
  21static phys_addr_t lwmon5_cfi_flash_bank_addr[2] = CONFIG_SYS_FLASH_BANKS_LIST;
  22
  23ulong flash_get_size(ulong base, int banknum);
  24int misc_init_r_kbd(void);
  25
  26int board_early_init_f(void)
  27{
  28        u32 sdr0_pfc1, sdr0_pfc2;
  29        u32 reg;
  30
  31        /* PLB Write pipelining disabled. Denali Core workaround */
  32        mtdcr(PLB4A0_ACR, 0xDE000000);
  33        mtdcr(PLB4A1_ACR, 0xDE000000);
  34
  35        /*--------------------------------------------------------------------
  36         * Setup the interrupt controller polarities, triggers, etc.
  37         *-------------------------------------------------------------------*/
  38        mtdcr(UIC0SR, 0xffffffff);  /* clear all. if write with 1 then the status is cleared  */
  39        mtdcr(UIC0ER, 0x00000000);  /* disable all */
  40        mtdcr(UIC0CR, 0x00000000);  /* we have not critical interrupts at the moment */
  41        mtdcr(UIC0PR, 0xFFBFF1EF);  /* Adjustment of the polarity */
  42        mtdcr(UIC0TR, 0x00000900);  /* per ref-board manual */
  43        mtdcr(UIC0VR, 0x00000000);  /* int31 highest, base=0x000 is within DDRAM */
  44        mtdcr(UIC0SR, 0xffffffff);  /* clear all */
  45
  46        mtdcr(UIC1SR, 0xffffffff);  /* clear all */
  47        mtdcr(UIC1ER, 0x00000000);  /* disable all */
  48        mtdcr(UIC1CR, 0x00000000);  /* all non-critical */
  49        mtdcr(UIC1PR, 0xFFFFC6A5);  /* Adjustment of the polarity */
  50        mtdcr(UIC1TR, 0x60000040);  /* per ref-board manual */
  51        mtdcr(UIC1VR, 0x00000000);  /* int31 highest, base=0x000 is within DDRAM */
  52        mtdcr(UIC1SR, 0xffffffff);  /* clear all */
  53
  54        mtdcr(UIC2SR, 0xffffffff);  /* clear all */
  55        mtdcr(UIC2ER, 0x00000000);  /* disable all */
  56        mtdcr(UIC2CR, 0x00000000);  /* all non-critical */
  57        mtdcr(UIC2PR, 0x27C00000);  /* Adjustment of the polarity */
  58        mtdcr(UIC2TR, 0x3C000000);  /* per ref-board manual */
  59        mtdcr(UIC2VR, 0x00000000);  /* int31 highest, base=0x000 is within DDRAM */
  60        mtdcr(UIC2SR, 0xffffffff);  /* clear all */
  61
  62        /* Trace Pins are disabled. SDR0_PFC0 Register */
  63        mtsdr(SDR0_PFC0, 0x0);
  64
  65        /* select Ethernet pins */
  66        mfsdr(SDR0_PFC1, sdr0_pfc1);
  67        /* SMII via ZMII */
  68        sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SELECT_MASK) |
  69                SDR0_PFC1_SELECT_CONFIG_6;
  70        mfsdr(SDR0_PFC2, sdr0_pfc2);
  71        sdr0_pfc2 = (sdr0_pfc2 & ~SDR0_PFC2_SELECT_MASK) |
  72                SDR0_PFC2_SELECT_CONFIG_6;
  73
  74        /* enable SPI (SCP) */
  75        sdr0_pfc1 = (sdr0_pfc1 & ~SDR0_PFC1_SIS_MASK) | SDR0_PFC1_SIS_SCP_SEL;
  76
  77        mtsdr(SDR0_PFC2, sdr0_pfc2);
  78        mtsdr(SDR0_PFC1, sdr0_pfc1);
  79
  80        mtsdr(SDR0_PFC4, 0x80000000);
  81
  82        /* PCI arbiter disabled */
  83        /* PCI Host Configuration disbaled */
  84        mfsdr(SDR0_PCI0, reg);
  85        reg = 0;
  86        mtsdr(SDR0_PCI0, 0x00000000 | reg);
  87
  88        gpio_write_bit(CONFIG_SYS_GPIO_FLASH_WP, 1);
  89
  90#if CONFIG_POST & CONFIG_SYS_POST_BSPEC1
  91        /* enable the LSB transmitter */
  92        gpio_write_bit(CONFIG_SYS_GPIO_LSB_ENABLE, 1);
  93        /* enable the CAN transmitter */
  94        gpio_write_bit(CONFIG_SYS_GPIO_CAN_ENABLE, 1);
  95
  96        reg = 0; /* reuse as counter */
  97        out_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR,
  98                in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR)
  99                        & ~CONFIG_SYS_DSPIC_TEST_MASK);
 100        while (gpio_read_in_bit(CONFIG_SYS_GPIO_DSPIC_READY) && reg++ < 1000) {
 101                udelay(1000);
 102        }
 103        if (gpio_read_in_bit(CONFIG_SYS_GPIO_DSPIC_READY)) {
 104                /* set "boot error" flag */
 105                out_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR,
 106                        in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR) |
 107                        CONFIG_SYS_DSPIC_TEST_MASK);
 108        }
 109#endif
 110
 111        /*
 112         * Reset PHY's:
 113         * The PHY's need a 2nd reset pulse, since the MDIO address is latched
 114         * upon reset, and with the first reset upon powerup, the addresses are
 115         * not latched reliable, since the IRQ line is multiplexed with an
 116         * MDIO address. A 2nd reset at this time will make sure, that the
 117         * correct address is latched.
 118         */
 119        gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 1);
 120        gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 1);
 121        udelay(1000);
 122        gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 0);
 123        gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 0);
 124        udelay(1000);
 125        gpio_write_bit(CONFIG_SYS_GPIO_PHY0_RST, 1);
 126        gpio_write_bit(CONFIG_SYS_GPIO_PHY1_RST, 1);
 127
 128        return 0;
 129}
 130
 131/*
 132 * Override weak default with board specific version
 133 */
 134phys_addr_t cfi_flash_bank_addr(int bank)
 135{
 136        return lwmon5_cfi_flash_bank_addr[bank];
 137}
 138
 139/*
 140 * Override the weak default mapping function with a board specific one
 141 */
 142u32 flash_get_bank_size(int cs, int idx)
 143{
 144        return flash_info[idx].size;
 145}
 146
 147int board_early_init_r(void)
 148{
 149        u32 val0, val1;
 150
 151        /*
 152         * lwmon5 is manufactured in 2 different board versions:
 153         * The lwmon5a board has 64MiB NOR flash instead of the
 154         * 128MiB of the original lwmon5. Unfortunately the CFI driver
 155         * will report 2 banks of 64MiB even for the smaller flash
 156         * chip, since the bank is mirrored. To fix this, we bring
 157         * one bank into CFI query mode and read its response. This
 158         * enables us to detect the real number of flash devices/
 159         * banks which will be used later on by the common CFI driver.
 160         */
 161
 162        /* Put bank 0 into CFI command mode and read */
 163        out_be32((void *)CONFIG_SYS_FLASH0, 0x00980098);
 164        val0 = in_be32((void *)CONFIG_SYS_FLASH0 + FLASH_OFFSET_CFI_RESP);
 165        val1 = in_be32((void *)CONFIG_SYS_FLASH1 + FLASH_OFFSET_CFI_RESP);
 166
 167        /* Reset flash again out of query mode */
 168        out_be32((void *)CONFIG_SYS_FLASH0, 0x00f000f0);
 169
 170        /* When not identical, we have 2 different flash devices/banks */
 171        if (val0 != val1)
 172                return 0;
 173
 174        /*
 175         * Now we're sure that we're running on a LWMON5a board with
 176         * only 64MiB NOR flash in one bank:
 177         *
 178         * Set flash base address and bank count for CFI driver probing.
 179         */
 180        cfi_flash_num_flash_banks = 1;
 181        lwmon5_cfi_flash_bank_addr[0] = CONFIG_SYS_FLASH0;
 182
 183        return 0;
 184}
 185
 186int misc_init_r(void)
 187{
 188        u32 pbcr;
 189        int size_val = 0;
 190        u32 reg;
 191        unsigned long usb2d0cr = 0;
 192        unsigned long usb2phy0cr, usb2h0cr = 0;
 193        unsigned long sdr0_pfc1, sdr0_srst;
 194
 195        /*
 196         * FLASH stuff...
 197         */
 198
 199        /* Re-do sizing to get full correct info */
 200
 201        /* adjust flash start and offset */
 202        gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
 203        gd->bd->bi_flashoffset = 0;
 204
 205        mfebc(PB0CR, pbcr);
 206        size_val = ffs(gd->bd->bi_flashsize) - 21;
 207        pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
 208        mtebc(PB0CR, pbcr);
 209
 210        /*
 211         * Re-check to get correct base address
 212         */
 213        flash_get_size(gd->bd->bi_flashstart, 0);
 214
 215        /* Monitor protection ON by default */
 216        flash_protect(FLAG_PROTECT_SET, -CONFIG_SYS_MONITOR_LEN, 0xffffffff,
 217                      &flash_info[cfi_flash_num_flash_banks - 1]);
 218
 219        /* Env protection ON by default */
 220        flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
 221                      CONFIG_ENV_ADDR_REDUND + 2 * CONFIG_ENV_SECT_SIZE - 1,
 222                      &flash_info[cfi_flash_num_flash_banks - 1]);
 223
 224        /*
 225         * USB suff...
 226         */
 227
 228        /* Reset USB */
 229        /* Reset of USB2PHY0 must be active at least 10 us  */
 230        mtsdr(SDR0_SRST0, SDR0_SRST0_USB2H | SDR0_SRST0_USB2D);
 231        udelay(2000);
 232
 233        mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY | SDR0_SRST1_USB2HUTMI |
 234              SDR0_SRST1_USB2HPHY | SDR0_SRST1_OPBA2 |
 235              SDR0_SRST1_PLB42OPB1 | SDR0_SRST1_OPB2PLB40);
 236        udelay(2000);
 237
 238        /* Errata CHIP_6 */
 239
 240        /* 1. Set internal PHY configuration */
 241        /* SDR Setting */
 242        mfsdr(SDR0_PFC1, sdr0_pfc1);
 243        mfsdr(SDR0_USB0, usb2d0cr);
 244        mfsdr(SDR0_USB2PHY0CR, usb2phy0cr);
 245        mfsdr(SDR0_USB2H0CR, usb2h0cr);
 246
 247        usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_XOCLK_MASK;
 248        usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_XOCLK_EXTERNAL;      /*0*/
 249        usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_WDINT_MASK;
 250        usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_WDINT_16BIT_30MHZ;   /*1*/
 251        usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_DVBUS_MASK;
 252        usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_DVBUS_PUREN;         /*1*/
 253        usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_DWNSTR_MASK;
 254        usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_DWNSTR_HOST;         /*1*/
 255        usb2phy0cr = usb2phy0cr & ~SDR0_USB2PHY0CR_UTMICN_MASK;
 256        usb2phy0cr = usb2phy0cr |  SDR0_USB2PHY0CR_UTMICN_HOST;         /*1*/
 257
 258        /*
 259         * An 8-bit/60MHz interface is the only possible alternative
 260         * when connecting the Device to the PHY
 261         */
 262        usb2h0cr   = usb2h0cr & ~SDR0_USB2H0CR_WDINT_MASK;
 263        usb2h0cr   = usb2h0cr |  SDR0_USB2H0CR_WDINT_16BIT_30MHZ;       /*1*/
 264
 265        mtsdr(SDR0_PFC1, sdr0_pfc1);
 266        mtsdr(SDR0_USB0, usb2d0cr);
 267        mtsdr(SDR0_USB2PHY0CR, usb2phy0cr);
 268        mtsdr(SDR0_USB2H0CR, usb2h0cr);
 269
 270        /* 2. De-assert internal PHY reset */
 271        mfsdr(SDR0_SRST1, sdr0_srst);
 272        sdr0_srst = sdr0_srst & ~SDR0_SRST1_USB20PHY;
 273        mtsdr(SDR0_SRST1, sdr0_srst);
 274
 275        /* 3. Wait for more than 1 ms */
 276        udelay(2000);
 277
 278        /* 4. De-assert USB 2.0 Host main reset */
 279        mfsdr(SDR0_SRST0, sdr0_srst);
 280        sdr0_srst = sdr0_srst &~ SDR0_SRST0_USB2H;
 281        mtsdr(SDR0_SRST0, sdr0_srst);
 282        udelay(1000);
 283
 284        /* 5. De-assert reset of OPB2 cores */
 285        mfsdr(SDR0_SRST1, sdr0_srst);
 286        sdr0_srst = sdr0_srst &~ SDR0_SRST1_PLB42OPB1;
 287        sdr0_srst = sdr0_srst &~ SDR0_SRST1_OPB2PLB40;
 288        sdr0_srst = sdr0_srst &~ SDR0_SRST1_OPBA2;
 289        mtsdr(SDR0_SRST1, sdr0_srst);
 290        udelay(1000);
 291
 292        /* 6. Set EHCI Configure FLAG */
 293
 294        /* 7. Reassert internal PHY reset: */
 295        mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY);
 296        udelay(1000);
 297
 298        /*
 299         * Clear resets
 300         */
 301        mtsdr(SDR0_SRST1, 0x00000000);
 302        mtsdr(SDR0_SRST0, 0x00000000);
 303
 304        printf("USB:   Host(int phy) Device(ext phy)\n");
 305
 306        /*
 307         * Clear PLB4A0_ACR[WRP]
 308         * This fix will make the MAL burst disabling patch for the Linux
 309         * EMAC driver obsolete.
 310         */
 311        reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK;
 312        mtdcr(PLB4A0_ACR, reg);
 313
 314        /*
 315         * Init matrix keyboard
 316         */
 317        misc_init_r_kbd();
 318
 319        return 0;
 320}
 321
 322int checkboard(void)
 323{
 324        char buf[64];
 325        int i = getenv_f("serial#", buf, sizeof(buf));
 326
 327        printf("Board: %s", __stringify(CONFIG_HOSTNAME));
 328
 329        if (i > 0) {
 330                puts(", serial# ");
 331                puts(buf);
 332        }
 333        putc('\n');
 334
 335        return (0);
 336}
 337
 338void hw_watchdog_reset(void)
 339{
 340        int val;
 341#if defined(CONFIG_WD_MAX_RATE)
 342        unsigned long long ct = get_ticks();
 343
 344        /*
 345         * Don't allow watch-dog triggering more frequently than
 346         * the predefined value CONFIG_WD_MAX_RATE [ticks].
 347         */
 348        if (ct >= gd->arch.wdt_last) {
 349                if ((ct - gd->arch.wdt_last) < CONFIG_WD_MAX_RATE)
 350                        return;
 351        } else {
 352                /* Time base counter had been reset */
 353                if (((unsigned long long)(-1) - gd->arch.wdt_last + ct) <
 354                    CONFIG_WD_MAX_RATE)
 355                        return;
 356        }
 357        gd->arch.wdt_last = get_ticks();
 358#endif
 359
 360        /*
 361         * Toggle watchdog output
 362         */
 363        val = gpio_read_out_bit(CONFIG_SYS_GPIO_WATCHDOG) == 0 ? 1 : 0;
 364        gpio_write_bit(CONFIG_SYS_GPIO_WATCHDOG, val);
 365}
 366
 367int do_eeprom_wp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 368{
 369        if (argc < 2)
 370                return cmd_usage(cmdtp);
 371
 372        if ((strcmp(argv[1], "on") == 0))
 373                gpio_write_bit(CONFIG_SYS_GPIO_EEPROM_EXT_WP, 1);
 374        else if ((strcmp(argv[1], "off") == 0))
 375                gpio_write_bit(CONFIG_SYS_GPIO_EEPROM_EXT_WP, 0);
 376        else
 377                return cmd_usage(cmdtp);
 378
 379        return 0;
 380}
 381
 382U_BOOT_CMD(
 383        eepromwp,       2,      0,      do_eeprom_wp,
 384        "eeprom write protect off/on",
 385        "<on|off> - enable (on) or disable (off) I2C EEPROM write protect"
 386);
 387
 388#if defined(CONFIG_VIDEO)
 389#include <video_fb.h>
 390#include <mb862xx.h>
 391
 392extern GraphicDevice mb862xx;
 393
 394static const gdc_regs init_regs [] = {
 395        { 0x0100, 0x00000f00 },
 396        { 0x0020, 0x801401df },
 397        { 0x0024, 0x00000000 },
 398        { 0x0028, 0x00000000 },
 399        { 0x002c, 0x00000000 },
 400        { 0x0110, 0x00000000 },
 401        { 0x0114, 0x00000000 },
 402        { 0x0118, 0x01df0280 },
 403        { 0x0004, 0x031f0000 },
 404        { 0x0008, 0x027f027f },
 405        { 0x000c, 0x015f028f },
 406        { 0x0010, 0x020c0000 },
 407        { 0x0014, 0x01df01ea },
 408        { 0x0018, 0x00000000 },
 409        { 0x001c, 0x01e00280 },
 410        { 0x0100, 0x80010f00 },
 411        { 0x0, 0x0 }
 412};
 413
 414const gdc_regs *board_get_regs(void)
 415{
 416        return init_regs;
 417}
 418
 419/* Returns Lime base address */
 420unsigned int board_video_init(void)
 421{
 422        /*
 423         * Reset Lime controller
 424         */
 425        gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1);
 426        udelay(500);
 427        gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1);
 428
 429        mb862xx.winSizeX = 640;
 430        mb862xx.winSizeY = 480;
 431        mb862xx.gdfBytesPP = 2;
 432        mb862xx.gdfIndex = GDF_15BIT_555RGB;
 433
 434        return CONFIG_SYS_LIME_BASE_0;
 435}
 436
 437#define DEFAULT_BRIGHTNESS      0x64
 438
 439static void board_backlight_brightness(int brightness)
 440{
 441        if (brightness > 0) {
 442                /* pwm duty, lamp on */
 443                out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000024), brightness);
 444                out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000020), 0x701);
 445        } else {
 446                /* lamp off */
 447                out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000024), 0x00);
 448                out_be32((void *)(CONFIG_SYS_FPGA_BASE_0 + 0x00000020), 0x00);
 449        }
 450}
 451
 452void board_backlight_switch(int flag)
 453{
 454        char * param;
 455        int rc;
 456
 457        if (flag) {
 458                param = getenv("brightness");
 459                rc = param ? simple_strtol(param, NULL, 10) : -1;
 460                if (rc < 0)
 461                        rc = DEFAULT_BRIGHTNESS;
 462        } else {
 463                rc = 0;
 464        }
 465        board_backlight_brightness(rc);
 466}
 467
 468#if defined(CONFIG_CONSOLE_EXTRA_INFO)
 469/*
 470 * Return text to be printed besides the logo.
 471 */
 472void video_get_info_str(int line_number, char *info)
 473{
 474        if (line_number == 1)
 475                strcpy(info, " Board: Lwmon5 (Liebherr Elektronik GmbH)");
 476        else
 477                info [0] = '\0';
 478}
 479#endif /* CONFIG_CONSOLE_EXTRA_INFO */
 480#endif /* CONFIG_VIDEO */
 481
 482void board_reset(void)
 483{
 484        gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1);
 485}
 486
 487#ifdef CONFIG_SPL_OS_BOOT
 488/*
 489 * lwmon5 specific implementation of spl_start_uboot()
 490 *
 491 * RETURN
 492 * 0 if booting into OS is selected (default)
 493 * 1 if booting into U-Boot is selected
 494 */
 495int spl_start_uboot(void)
 496{
 497        char s[8];
 498
 499        env_init();
 500        getenv_f("boot_os", s, sizeof(s));
 501        if ((s != NULL) && (strcmp(s, "yes") == 0))
 502                return 0;
 503
 504        return 1;
 505}
 506
 507/*
 508 * This function is called from the SPL U-Boot version for
 509 * early init stuff, that needs to be done for OS (e.g. Linux)
 510 * booting. Doing it later in the real U-Boot would not work
 511 * in case that the SPL U-Boot boots Linux directly.
 512 */
 513void spl_board_init(void)
 514{
 515        const gdc_regs *regs = board_get_regs();
 516
 517        /*
 518         * Setup PFC registers, mainly for ethernet support
 519         * later on in Linux
 520         */
 521        board_early_init_f();
 522
 523        /* enable the LSB transmitter */
 524        gpio_write_bit(CONFIG_SYS_GPIO_LSB_ENABLE, 1);
 525
 526        /*
 527         * Clear resets
 528         */
 529        mtsdr(SDR0_SRST1, 0x00000000);
 530        mtsdr(SDR0_SRST0, 0x00000000);
 531
 532        /*
 533         * Reset Lime controller
 534         */
 535        gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1);
 536        udelay(500);
 537        gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1);
 538
 539        out_be32((void *)CONFIG_SYS_LIME_SDRAM_CLOCK, CONFIG_SYS_MB862xx_CCF);
 540        udelay(300);
 541        out_be32((void *)CONFIG_SYS_LIME_MMR, CONFIG_SYS_MB862xx_MMR);
 542
 543        while (regs->index) {
 544                out_be32((void *)(CONFIG_SYS_LIME_BASE_0 + GC_DISP_BASE) +
 545                         regs->index, regs->value);
 546                regs++;
 547        }
 548
 549        board_backlight_brightness(DEFAULT_BRIGHTNESS);
 550}
 551#endif
 552