uboot/board/gdsys/405ex/io64.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2010
   3 * Dirk Eibach,  Guntermann & Drunck GmbH, eibach@gdsys.de
   4 *
   5 * based on kilauea.c
   6 * by Stefan Roese, DENX Software Engineering, sr@denx.de.
   7 *
   8 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11#include <common.h>
  12#include <asm/ppc4xx.h>
  13#include <asm/ppc405.h>
  14#include <libfdt.h>
  15#include <fdt_support.h>
  16#include <asm/processor.h>
  17#include <asm/io.h>
  18#include <linux/errno.h>
  19#include <asm/ppc4xx-gpio.h>
  20#include <flash.h>
  21
  22#include <pca9698.h>
  23
  24#include "405ex.h"
  25#include <gdsys_fpga.h>
  26
  27#include <miiphy.h>
  28#include <i2c.h>
  29#include <dtt.h>
  30
  31DECLARE_GLOBAL_DATA_PTR;
  32
  33#define PHYREG_CONTROL                          0
  34#define PHYREG_PAGE_ADDRESS                     22
  35#define PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1    16
  36#define PHYREG_PG2_COPPER_SPECIFIC_CONTROL_2    26
  37#define PHYREG_PG2_MAC_SPECIFIC_STATUS_1        17
  38#define PHYREG_PG2_MAC_SPECIFIC_CONTROL         21
  39
  40#define LATCH0_BASE (CONFIG_SYS_LATCH_BASE)
  41#define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100)
  42#define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200)
  43#define LATCH3_BASE (CONFIG_SYS_LATCH_BASE + 0x300)
  44
  45enum {
  46        UNITTYPE_CCD_SWITCH = 1,
  47};
  48
  49enum {
  50        HWVER_100 = 0,
  51        HWVER_110 = 1,
  52};
  53
  54struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
  55
  56static inline void blank_string(int size)
  57{
  58        int i;
  59
  60        for (i = 0; i < size; i++)
  61                putc('\b');
  62        for (i = 0; i < size; i++)
  63                putc(' ');
  64        for (i = 0; i < size; i++)
  65                putc('\b');
  66}
  67
  68/*
  69 * Board early initialization function
  70 */
  71int misc_init_r(void)
  72{
  73        /* startup fans */
  74        dtt_init();
  75
  76#ifdef CONFIG_ENV_IS_IN_FLASH
  77        /* Monitor protection ON by default */
  78        flash_protect(FLAG_PROTECT_SET,
  79                      -CONFIG_SYS_MONITOR_LEN,
  80                      0xffffffff,
  81                      &flash_info[0]);
  82#endif
  83
  84        return 0;
  85}
  86
  87static void print_fpga_info(unsigned dev)
  88{
  89        u16 versions;
  90        u16 fpga_version;
  91        u16 fpga_features;
  92        int fpga_state = get_fpga_state(dev);
  93
  94        unsigned unit_type;
  95        unsigned hardware_version;
  96        unsigned feature_channels;
  97        unsigned feature_expansion;
  98
  99        FPGA_GET_REG(dev, versions, &versions);
 100        FPGA_GET_REG(dev, fpga_version, &fpga_version);
 101        FPGA_GET_REG(dev, fpga_features, &fpga_features);
 102
 103        printf("FPGA%d: ", dev);
 104        if (fpga_state & FPGA_STATE_PLATFORM)
 105                printf("(legacy) ");
 106
 107        if (fpga_state & FPGA_STATE_DONE_FAILED) {
 108                printf(" done timed out\n");
 109                return;
 110        }
 111
 112        if (fpga_state & FPGA_STATE_REFLECTION_FAILED) {
 113                printf(" refelectione test failed\n");
 114                return;
 115        }
 116
 117        unit_type = (versions & 0xf000) >> 12;
 118        hardware_version = versions & 0x000f;
 119        feature_channels = fpga_features & 0x007f;
 120        feature_expansion = fpga_features & (1<<15);
 121
 122        switch (unit_type) {
 123        case UNITTYPE_CCD_SWITCH:
 124                printf("CCD-Switch");
 125                break;
 126
 127        default:
 128                printf("UnitType %d(not supported)", unit_type);
 129                break;
 130        }
 131
 132        switch (hardware_version) {
 133        case HWVER_100:
 134                printf(" HW-Ver 1.00\n");
 135                break;
 136
 137        case HWVER_110:
 138                printf(" HW-Ver 1.10\n");
 139                break;
 140
 141        default:
 142                printf(" HW-Ver %d(not supported)\n",
 143                       hardware_version);
 144                break;
 145        }
 146
 147        printf("       FPGA V %d.%02d, features:",
 148                fpga_version / 100, fpga_version % 100);
 149
 150        printf(" %d channel(s)", feature_channels);
 151
 152        printf(", expansion %ssupported\n", feature_expansion ? "" : "un");
 153}
 154
 155int checkboard(void)
 156{
 157        char *s = getenv("serial#");
 158
 159        printf("Board: CATCenter Io64\n");
 160
 161        if (s != NULL) {
 162                puts(", serial# ");
 163                puts(s);
 164        }
 165
 166        return 0;
 167}
 168
 169int configure_gbit_phy(char *bus, unsigned char addr)
 170{
 171        unsigned short value;
 172
 173        /* select page 0 */
 174        if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000))
 175                goto err_out;
 176        /* switch to powerdown */
 177        if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
 178                &value))
 179                goto err_out;
 180        if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
 181                value | 0x0004))
 182                goto err_out;
 183        /* select page 2 */
 184        if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002))
 185                goto err_out;
 186        /* disable SGMII autonegotiation */
 187        if (miiphy_write(bus, addr, PHYREG_PG2_MAC_SPECIFIC_CONTROL, 48))
 188                goto err_out;
 189        /* select page 0 */
 190        if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0000))
 191                goto err_out;
 192        /* switch from powerdown to normal operation */
 193        if (miiphy_read(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
 194                &value))
 195                goto err_out;
 196        if (miiphy_write(bus, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1,
 197                value & ~0x0004))
 198                goto err_out;
 199        /* reset phy so settings take effect */
 200        if (miiphy_write(bus, addr, PHYREG_CONTROL, 0x9140))
 201                goto err_out;
 202
 203        return 0;
 204
 205err_out:
 206        printf("Error writing to the PHY addr=%02x\n", addr);
 207        return -1;
 208}
 209
 210int verify_gbit_phy(char *bus, unsigned char addr)
 211{
 212        unsigned short value;
 213
 214        /* select page 2 */
 215        if (miiphy_write(bus, addr, PHYREG_PAGE_ADDRESS, 0x0002))
 216                goto err_out;
 217        /* verify SGMII link status */
 218        if (miiphy_read(bus, addr, PHYREG_PG2_MAC_SPECIFIC_STATUS_1, &value))
 219                goto err_out;
 220        if (!(value & (1 << 10)))
 221                return -2;
 222
 223        return 0;
 224
 225err_out:
 226        printf("Error writing to the PHY addr=%02x\n", addr);
 227        return -1;
 228}
 229
 230int last_stage_init(void)
 231{
 232        unsigned int k;
 233        unsigned int fpga;
 234        int failed = 0;
 235        char str_phys[] = "Setup PHYs -";
 236        char str_serdes[] = "Start SERDES blocks";
 237        char str_channels[] = "Start FPGA channels";
 238        char str_locks[] = "Verify SERDES locks";
 239        char str_hicb[] = "Verify HICB status";
 240        char str_status[] = "Verify PHY status -";
 241        char slash[] = "\\|/-\\|/-";
 242
 243        print_fpga_info(0);
 244        print_fpga_info(1);
 245
 246        /* setup Gbit PHYs */
 247        puts("TRANS: ");
 248        puts(str_phys);
 249        int retval;
 250        struct mii_dev *mdiodev = mdio_alloc();
 251        if (!mdiodev)
 252                return -ENOMEM;
 253        strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII_BUSNAME, MDIO_NAME_LEN);
 254        mdiodev->read = bb_miiphy_read;
 255        mdiodev->write = bb_miiphy_write;
 256
 257        retval = mdio_register(mdiodev);
 258        if (retval < 0)
 259                return retval;
 260
 261        for (k = 0; k < 32; ++k) {
 262                configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k);
 263                putc('\b');
 264                putc(slash[k % 8]);
 265        }
 266
 267        mdiodev = mdio_alloc();
 268        if (!mdiodev)
 269                return -ENOMEM;
 270        strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII1_BUSNAME, MDIO_NAME_LEN);
 271        mdiodev->read = bb_miiphy_read;
 272        mdiodev->write = bb_miiphy_write;
 273
 274        retval = mdio_register(mdiodev);
 275        if (retval < 0)
 276                return retval;
 277
 278        for (k = 0; k < 32; ++k) {
 279                configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k);
 280                putc('\b');
 281                putc(slash[k % 8]);
 282        }
 283        blank_string(strlen(str_phys));
 284
 285        /* take fpga serdes blocks out of reset */
 286        puts(str_serdes);
 287        udelay(500000);
 288        FPGA_SET_REG(0, quad_serdes_reset, 0);
 289        FPGA_SET_REG(1, quad_serdes_reset, 0);
 290        blank_string(strlen(str_serdes));
 291
 292        /* take channels out of reset */
 293        puts(str_channels);
 294        udelay(500000);
 295        for (fpga = 0; fpga < 2; ++fpga) {
 296                for (k = 0; k < 32; ++k)
 297                        FPGA_SET_REG(fpga, ch[k].config_int, 0);
 298        }
 299        blank_string(strlen(str_channels));
 300
 301        /* verify channels serdes lock */
 302        puts(str_locks);
 303        udelay(500000);
 304        for (fpga = 0; fpga < 2; ++fpga) {
 305                for (k = 0; k < 32; ++k) {
 306                        u16 status;
 307                        FPGA_GET_REG(fpga, ch[k].status_int, &status);
 308                        if (!(status & (1 << 4))) {
 309                                failed = 1;
 310                                printf("fpga %d channel %d: no serdes lock\n",
 311                                        fpga, k);
 312                        }
 313                        /* reset events */
 314                        FPGA_SET_REG(fpga, ch[k].status_int, 0);
 315                }
 316        }
 317        blank_string(strlen(str_locks));
 318
 319        /* verify hicb_status */
 320        puts(str_hicb);
 321        for (fpga = 0; fpga < 2; ++fpga) {
 322                for (k = 0; k < 32; ++k) {
 323                        u16 status;
 324                        FPGA_GET_REG(fpga, hicb_ch[k].status_int, &status);
 325                        if (status)
 326                                printf("fpga %d hicb %d: hicb status %04x\n",
 327                                        fpga, k, status);
 328                        /* reset events */
 329                        FPGA_SET_REG(fpga, hicb_ch[k].status_int, 0);
 330                }
 331        }
 332        blank_string(strlen(str_hicb));
 333
 334        /* verify phy status */
 335        puts(str_status);
 336        for (k = 0; k < 32; ++k) {
 337                if (verify_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k)) {
 338                        printf("verify baseboard phy %d failed\n", k);
 339                        failed = 1;
 340                }
 341                putc('\b');
 342                putc(slash[k % 8]);
 343        }
 344        for (k = 0; k < 32; ++k) {
 345                if (verify_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k)) {
 346                        printf("verify extensionboard phy %d failed\n", k);
 347                        failed = 1;
 348                }
 349                putc('\b');
 350                putc(slash[k % 8]);
 351        }
 352        blank_string(strlen(str_status));
 353
 354        printf("Starting 64 channels %s\n", failed ? "failed" : "ok");
 355
 356        return 0;
 357}
 358
 359void gd405ex_init(void)
 360{
 361        unsigned int k;
 362
 363        if (i2c_probe(0x22)) { /* i2c_probe returns 0 on success */
 364                for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
 365                        gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
 366        } else {
 367                pca9698_direction_output(0x22, 39, 1);
 368        }
 369}
 370
 371void gd405ex_set_fpga_reset(unsigned state)
 372{
 373        int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
 374
 375        if (legacy) {
 376                if (state) {
 377                        out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
 378                        out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
 379                } else {
 380                        out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
 381                        out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
 382                }
 383        } else {
 384                pca9698_set_value(0x22, 39, state ? 0 : 1);
 385        }
 386}
 387
 388void gd405ex_setup_hw(void)
 389{
 390        gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED_N, 0);
 391        gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED, 1);
 392}
 393
 394int gd405ex_get_fpga_done(unsigned fpga)
 395{
 396        int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
 397
 398        if (legacy)
 399                return in_le16((void *)LATCH3_BASE)
 400                        & CONFIG_SYS_FPGA_DONE(fpga);
 401        else
 402                return pca9698_get_value(0x22, fpga ? 9 : 8);
 403}
 404