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 <asm/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        miiphy_register(CONFIG_SYS_GBIT_MII_BUSNAME,
 250                bb_miiphy_read, bb_miiphy_write);
 251
 252        for (k = 0; k < 32; ++k) {
 253                configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k);
 254                putc('\b');
 255                putc(slash[k % 8]);
 256        }
 257
 258        miiphy_register(CONFIG_SYS_GBIT_MII1_BUSNAME,
 259                bb_miiphy_read, bb_miiphy_write);
 260
 261        for (k = 0; k < 32; ++k) {
 262                configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k);
 263                putc('\b');
 264                putc(slash[k % 8]);
 265        }
 266        blank_string(strlen(str_phys));
 267
 268        /* take fpga serdes blocks out of reset */
 269        puts(str_serdes);
 270        udelay(500000);
 271        FPGA_SET_REG(0, quad_serdes_reset, 0);
 272        FPGA_SET_REG(1, quad_serdes_reset, 0);
 273        blank_string(strlen(str_serdes));
 274
 275        /* take channels out of reset */
 276        puts(str_channels);
 277        udelay(500000);
 278        for (fpga = 0; fpga < 2; ++fpga) {
 279                for (k = 0; k < 32; ++k)
 280                        FPGA_SET_REG(fpga, ch[k].config_int, 0);
 281        }
 282        blank_string(strlen(str_channels));
 283
 284        /* verify channels serdes lock */
 285        puts(str_locks);
 286        udelay(500000);
 287        for (fpga = 0; fpga < 2; ++fpga) {
 288                for (k = 0; k < 32; ++k) {
 289                        u16 status;
 290                        FPGA_GET_REG(fpga, ch[k].status_int, &status);
 291                        if (!(status & (1 << 4))) {
 292                                failed = 1;
 293                                printf("fpga %d channel %d: no serdes lock\n",
 294                                        fpga, k);
 295                        }
 296                        /* reset events */
 297                        FPGA_SET_REG(fpga, ch[k].status_int, 0);
 298                }
 299        }
 300        blank_string(strlen(str_locks));
 301
 302        /* verify hicb_status */
 303        puts(str_hicb);
 304        for (fpga = 0; fpga < 2; ++fpga) {
 305                for (k = 0; k < 32; ++k) {
 306                        u16 status;
 307                        FPGA_GET_REG(fpga, hicb_ch[k].status_int, &status);
 308                        if (status)
 309                                printf("fpga %d hicb %d: hicb status %04x\n",
 310                                        fpga, k, status);
 311                        /* reset events */
 312                        FPGA_SET_REG(fpga, hicb_ch[k].status_int, 0);
 313                }
 314        }
 315        blank_string(strlen(str_hicb));
 316
 317        /* verify phy status */
 318        puts(str_status);
 319        for (k = 0; k < 32; ++k) {
 320                if (verify_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k)) {
 321                        printf("verify baseboard phy %d failed\n", k);
 322                        failed = 1;
 323                }
 324                putc('\b');
 325                putc(slash[k % 8]);
 326        }
 327        for (k = 0; k < 32; ++k) {
 328                if (verify_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k)) {
 329                        printf("verify extensionboard phy %d failed\n", k);
 330                        failed = 1;
 331                }
 332                putc('\b');
 333                putc(slash[k % 8]);
 334        }
 335        blank_string(strlen(str_status));
 336
 337        printf("Starting 64 channels %s\n", failed ? "failed" : "ok");
 338
 339        return 0;
 340}
 341
 342void gd405ex_init(void)
 343{
 344        unsigned int k;
 345
 346        if (i2c_probe(0x22)) { /* i2c_probe returns 0 on success */
 347                for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
 348                        gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
 349        } else {
 350                pca9698_direction_output(0x22, 39, 1);
 351        }
 352}
 353
 354void gd405ex_set_fpga_reset(unsigned state)
 355{
 356        int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
 357
 358        if (legacy) {
 359                if (state) {
 360                        out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
 361                        out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
 362                } else {
 363                        out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
 364                        out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
 365                }
 366        } else {
 367                pca9698_set_value(0x22, 39, state ? 0 : 1);
 368        }
 369}
 370
 371void gd405ex_setup_hw(void)
 372{
 373        gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED_N, 0);
 374        gpio_write_bit(CONFIG_SYS_GPIO_STARTUP_FINISHED, 1);
 375}
 376
 377int gd405ex_get_fpga_done(unsigned fpga)
 378{
 379        int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
 380
 381        if (legacy)
 382                return in_le16((void *)LATCH3_BASE)
 383                        & CONFIG_SYS_FPGA_DONE(fpga);
 384        else
 385                return pca9698_get_value(0x22, fpga ? 9 : 8);
 386}
 387