uboot/board/CZ.NIC/turris_mox/turris_mox.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
   4 */
   5
   6#include <common.h>
   7#include <asm/arch/cpu.h>
   8#include <asm/arch/soc.h>
   9#include <net.h>
  10#include <asm/io.h>
  11#include <asm/gpio.h>
  12#include <clk.h>
  13#include <dm.h>
  14#include <env.h>
  15#include <fdt_support.h>
  16#include <init.h>
  17#include <linux/delay.h>
  18#include <linux/libfdt.h>
  19#include <linux/string.h>
  20#include <miiphy.h>
  21#include <mvebu/comphy.h>
  22#include <spi.h>
  23
  24#include "mox_sp.h"
  25
  26#define MAX_MOX_MODULES         10
  27
  28#define MOX_MODULE_SFP          0x1
  29#define MOX_MODULE_PCI          0x2
  30#define MOX_MODULE_TOPAZ        0x3
  31#define MOX_MODULE_PERIDOT      0x4
  32#define MOX_MODULE_USB3         0x5
  33#define MOX_MODULE_PASSPCI      0x6
  34
  35#define ARMADA_37XX_NB_GPIO_SEL (MVEBU_REGISTER(0x13830))
  36#define ARMADA_37XX_SPI_CTRL    (MVEBU_REGISTER(0x10600))
  37#define ARMADA_37XX_SPI_CFG     (MVEBU_REGISTER(0x10604))
  38#define ARMADA_37XX_SPI_DOUT    (MVEBU_REGISTER(0x10608))
  39#define ARMADA_37XX_SPI_DIN     (MVEBU_REGISTER(0x1060c))
  40
  41#define ETH1_PATH       "/soc/internal-regs@d0000000/ethernet@40000"
  42#define MDIO_PATH       "/soc/internal-regs@d0000000/mdio@32004"
  43#define SFP_GPIO_PATH   "/soc/internal-regs@d0000000/spi@10600/moxtet@1/gpio@0"
  44#define PCIE_PATH       "/soc/pcie@d0070000"
  45#define SFP_PATH        "/sfp"
  46
  47DECLARE_GLOBAL_DATA_PTR;
  48
  49#if defined(CONFIG_OF_BOARD_FIXUP)
  50int board_fix_fdt(void *blob)
  51{
  52        u8 topology[MAX_MOX_MODULES];
  53        int i, size, node;
  54        bool enable;
  55
  56        /*
  57         * SPI driver is not loaded in driver model yet, but we have to find out
  58         * if pcie should be enabled in U-Boot's device tree. Therefore we have
  59         * to read SPI by reading/writing SPI registers directly
  60         */
  61
  62        writel(0x10df, ARMADA_37XX_SPI_CFG);
  63        /* put pin from GPIO to SPI mode */
  64        clrbits_le32(ARMADA_37XX_NB_GPIO_SEL, BIT(12));
  65        /* enable SPI CS1 */
  66        setbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17));
  67
  68        while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
  69                udelay(1);
  70
  71        for (i = 0; i < MAX_MOX_MODULES; ++i) {
  72                writel(0x0, ARMADA_37XX_SPI_DOUT);
  73
  74                while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
  75                        udelay(1);
  76
  77                topology[i] = readl(ARMADA_37XX_SPI_DIN) & 0xff;
  78                if (topology[i] == 0xff)
  79                        break;
  80
  81                topology[i] &= 0xf;
  82        }
  83
  84        size = i;
  85
  86        /* disable SPI CS1 */
  87        clrbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17));
  88
  89        if (size > 1 && (topology[1] == MOX_MODULE_PCI ||
  90                         topology[1] == MOX_MODULE_USB3 ||
  91                         topology[1] == MOX_MODULE_PASSPCI))
  92                enable = true;
  93        else
  94                enable = false;
  95
  96        node = fdt_path_offset(blob, PCIE_PATH);
  97
  98        if (node < 0) {
  99                printf("Cannot find PCIe node in U-Boot's device tree!\n");
 100                return 0;
 101        }
 102
 103        if (fdt_setprop_string(blob, node, "status",
 104                               enable ? "okay" : "disabled") < 0) {
 105                printf("Cannot %s PCIe in U-Boot's device tree!\n",
 106                       enable ? "enable" : "disable");
 107                return 0;
 108        }
 109
 110        if (a3700_fdt_fix_pcie_regions(blob) < 0) {
 111                printf("Cannot fix PCIe regions in U-Boot's device tree!\n");
 112                return 0;
 113        }
 114
 115        return 0;
 116}
 117#endif
 118
 119int board_init(void)
 120{
 121        /* address of boot parameters */
 122        gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 123
 124        return 0;
 125}
 126
 127static int mox_do_spi(u8 *in, u8 *out, size_t size)
 128{
 129        struct spi_slave *slave;
 130        struct udevice *dev;
 131        int ret;
 132
 133        ret = spi_get_bus_and_cs(0, 1, 1000000, SPI_CPHA | SPI_CPOL,
 134                                 "spi_generic_drv", "moxtet@1", &dev,
 135                                 &slave);
 136        if (ret)
 137                goto fail;
 138
 139        ret = spi_claim_bus(slave);
 140        if (ret)
 141                goto fail_free;
 142
 143        ret = spi_xfer(slave, size * 8, out, in, SPI_XFER_ONCE);
 144
 145        spi_release_bus(slave);
 146fail_free:
 147        spi_free_slave(slave);
 148fail:
 149        return ret;
 150}
 151
 152static int mox_get_topology(const u8 **ptopology, int *psize, int *pis_sd)
 153{
 154        static int is_sd;
 155        static u8 topology[MAX_MOX_MODULES - 1];
 156        static int size;
 157        u8 din[MAX_MOX_MODULES], dout[MAX_MOX_MODULES];
 158        int ret, i;
 159
 160        if (size) {
 161                if (ptopology)
 162                        *ptopology = topology;
 163                if (psize)
 164                        *psize = size;
 165                if (pis_sd)
 166                        *pis_sd = is_sd;
 167                return 0;
 168        }
 169
 170        memset(din, 0, MAX_MOX_MODULES);
 171        memset(dout, 0, MAX_MOX_MODULES);
 172
 173        ret = mox_do_spi(din, dout, MAX_MOX_MODULES);
 174        if (ret)
 175                return ret;
 176
 177        if (din[0] == 0x10)
 178                is_sd = 1;
 179        else if (din[0] == 0x00)
 180                is_sd = 0;
 181        else
 182                return -ENODEV;
 183
 184        for (i = 1; i < MAX_MOX_MODULES && din[i] != 0xff; ++i)
 185                topology[i - 1] = din[i] & 0xf;
 186        size = i - 1;
 187
 188        if (ptopology)
 189                *ptopology = topology;
 190        if (psize)
 191                *psize = size;
 192        if (pis_sd)
 193                *pis_sd = is_sd;
 194
 195        return 0;
 196}
 197
 198int comphy_update_map(struct comphy_map *serdes_map, int count)
 199{
 200        int ret, i, size, sfpindex = -1, swindex = -1;
 201        const u8 *topology;
 202
 203        ret = mox_get_topology(&topology, &size, NULL);
 204        if (ret)
 205                return ret;
 206
 207        for (i = 0; i < size; ++i) {
 208                if (topology[i] == MOX_MODULE_SFP && sfpindex == -1)
 209                        sfpindex = i;
 210                else if ((topology[i] == MOX_MODULE_TOPAZ ||
 211                          topology[i] == MOX_MODULE_PERIDOT) &&
 212                         swindex == -1)
 213                        swindex = i;
 214        }
 215
 216        if (sfpindex >= 0 && swindex >= 0) {
 217                if (sfpindex < swindex)
 218                        serdes_map[0].speed = PHY_SPEED_1_25G;
 219                else
 220                        serdes_map[0].speed = PHY_SPEED_3_125G;
 221        } else if (sfpindex >= 0) {
 222                serdes_map[0].speed = PHY_SPEED_1_25G;
 223        } else if (swindex >= 0) {
 224                serdes_map[0].speed = PHY_SPEED_3_125G;
 225        }
 226
 227        return 0;
 228}
 229
 230#define SW_SMI_CMD_R(d, r)      (0x9800 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
 231#define SW_SMI_CMD_W(d, r)      (0x9400 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
 232
 233static int sw_multi_read(struct mii_dev *bus, int sw, int dev, int reg)
 234{
 235        bus->write(bus, sw, 0, 0, SW_SMI_CMD_R(dev, reg));
 236        mdelay(5);
 237        return bus->read(bus, sw, 0, 1);
 238}
 239
 240static void sw_multi_write(struct mii_dev *bus, int sw, int dev, int reg,
 241                           u16 val)
 242{
 243        bus->write(bus, sw, 0, 1, val);
 244        bus->write(bus, sw, 0, 0, SW_SMI_CMD_W(dev, reg));
 245        mdelay(5);
 246}
 247
 248static int sw_scratch_read(struct mii_dev *bus, int sw, int reg)
 249{
 250        sw_multi_write(bus, sw, 0x1c, 0x1a, (reg & 0x7f) << 8);
 251        return sw_multi_read(bus, sw, 0x1c, 0x1a) & 0xff;
 252}
 253
 254static void sw_led_write(struct mii_dev *bus, int sw, int port, int reg,
 255                         u16 val)
 256{
 257        sw_multi_write(bus, sw, port, 0x16, 0x8000 | ((reg & 7) << 12)
 258                                            | (val & 0x7ff));
 259}
 260
 261static void sw_blink_leds(struct mii_dev *bus, int peridot, int topaz)
 262{
 263        int i, p;
 264        struct {
 265                int port;
 266                u16 val;
 267                int wait;
 268        } regs[] = {
 269                { 2, 0xef, 1 }, { 2, 0xfe, 1 }, { 2, 0x33, 0 },
 270                { 4, 0xef, 1 }, { 4, 0xfe, 1 }, { 4, 0x33, 0 },
 271                { 3, 0xfe, 1 }, { 3, 0xef, 1 }, { 3, 0x33, 0 },
 272                { 1, 0xfe, 1 }, { 1, 0xef, 1 }, { 1, 0x33, 0 }
 273        };
 274
 275        for (i = 0; i < 12; ++i) {
 276                for (p = 0; p < peridot; ++p) {
 277                        sw_led_write(bus, 0x10 + p, regs[i].port, 0,
 278                                     regs[i].val);
 279                        sw_led_write(bus, 0x10 + p, regs[i].port + 4, 0,
 280                                     regs[i].val);
 281                }
 282                if (topaz) {
 283                        sw_led_write(bus, 0x2, 0x10 + regs[i].port, 0,
 284                                     regs[i].val);
 285                }
 286
 287                if (regs[i].wait)
 288                        mdelay(75);
 289        }
 290}
 291
 292static void check_switch_address(struct mii_dev *bus, int addr)
 293{
 294        if (sw_scratch_read(bus, addr, 0x70) >> 3 != addr)
 295                printf("Check of switch MDIO address failed for 0x%02x\n",
 296                       addr);
 297}
 298
 299static int sfp, pci, topaz, peridot, usb, passpci;
 300static int sfp_pos, peridot_pos[3];
 301static int module_count;
 302
 303static int configure_peridots(struct gpio_desc *reset_gpio)
 304{
 305        int i, ret;
 306        u8 dout[MAX_MOX_MODULES];
 307
 308        memset(dout, 0, MAX_MOX_MODULES);
 309
 310        /* set addresses of Peridot modules */
 311        for (i = 0; i < peridot; ++i)
 312                dout[module_count - peridot_pos[i]] = (~i) & 3;
 313
 314        /*
 315         * if there is a SFP module connected to the last Peridot module, set
 316         * the P10_SMODE to 1 for the Peridot module
 317         */
 318        if (sfp)
 319                dout[module_count - peridot_pos[i - 1]] |= 1 << 3;
 320
 321        dm_gpio_set_value(reset_gpio, 1);
 322        mdelay(10);
 323
 324        ret = mox_do_spi(NULL, dout, module_count + 1);
 325
 326        mdelay(10);
 327        dm_gpio_set_value(reset_gpio, 0);
 328
 329        mdelay(50);
 330
 331        return ret;
 332}
 333
 334static int get_reset_gpio(struct gpio_desc *reset_gpio)
 335{
 336        int node;
 337
 338        node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "cznic,moxtet");
 339        if (node < 0) {
 340                printf("Cannot find Moxtet bus device node!\n");
 341                return -1;
 342        }
 343
 344        gpio_request_by_name_nodev(offset_to_ofnode(node), "reset-gpios", 0,
 345                                   reset_gpio, GPIOD_IS_OUT);
 346
 347        if (!dm_gpio_is_valid(reset_gpio)) {
 348                printf("Cannot find reset GPIO for Moxtet bus!\n");
 349                return -1;
 350        }
 351
 352        return 0;
 353}
 354
 355int misc_init_r(void)
 356{
 357        int ret;
 358        u8 mac1[6], mac2[6];
 359
 360        ret = mbox_sp_get_board_info(NULL, mac1, mac2, NULL, NULL);
 361        if (ret < 0) {
 362                printf("Cannot read data from OTP!\n");
 363                return 0;
 364        }
 365
 366        if (is_valid_ethaddr(mac1) && !env_get("ethaddr"))
 367                eth_env_set_enetaddr("ethaddr", mac1);
 368
 369        if (is_valid_ethaddr(mac2) && !env_get("eth1addr"))
 370                eth_env_set_enetaddr("eth1addr", mac2);
 371
 372        return 0;
 373}
 374
 375static void mox_print_info(void)
 376{
 377        int ret, board_version, ram_size;
 378        u64 serial_number;
 379        const char *pub_key;
 380
 381        ret = mbox_sp_get_board_info(&serial_number, NULL, NULL, &board_version,
 382                                     &ram_size);
 383        if (ret < 0)
 384                return;
 385
 386        printf("Turris Mox:\n");
 387        printf("  Board version: %i\n", board_version);
 388        printf("  RAM size: %i MiB\n", ram_size);
 389        printf("  Serial Number: %016llX\n", serial_number);
 390
 391        pub_key = mox_sp_get_ecdsa_public_key();
 392        if (pub_key)
 393                printf("  ECDSA Public Key: %s\n", pub_key);
 394        else
 395                printf("Cannot read ECDSA Public Key\n");
 396}
 397
 398int last_stage_init(void)
 399{
 400        int ret, i;
 401        const u8 *topology;
 402        int is_sd;
 403        struct mii_dev *bus;
 404        struct gpio_desc reset_gpio = {};
 405
 406        mox_print_info();
 407
 408        ret = mox_get_topology(&topology, &module_count, &is_sd);
 409        if (ret) {
 410                printf("Cannot read module topology!\n");
 411                return 0;
 412        }
 413
 414        printf("  SD/eMMC version: %s\n", is_sd ? "SD" : "eMMC");
 415
 416        if (module_count)
 417                printf("Module Topology:\n");
 418
 419        for (i = 0; i < module_count; ++i) {
 420                switch (topology[i]) {
 421                case MOX_MODULE_SFP:
 422                        printf("% 4i: SFP Module\n", i + 1);
 423                        break;
 424                case MOX_MODULE_PCI:
 425                        printf("% 4i: Mini-PCIe Module\n", i + 1);
 426                        break;
 427                case MOX_MODULE_TOPAZ:
 428                        printf("% 4i: Topaz Switch Module (4-port)\n", i + 1);
 429                        break;
 430                case MOX_MODULE_PERIDOT:
 431                        printf("% 4i: Peridot Switch Module (8-port)\n", i + 1);
 432                        break;
 433                case MOX_MODULE_USB3:
 434                        printf("% 4i: USB 3.0 Module (4 ports)\n", i + 1);
 435                        break;
 436                case MOX_MODULE_PASSPCI:
 437                        printf("% 4i: Passthrough Mini-PCIe Module\n", i + 1);
 438                        break;
 439                default:
 440                        printf("% 4i: unknown (ID %i)\n", i + 1, topology[i]);
 441                }
 442        }
 443
 444        /* now check if modules are connected in supported mode */
 445
 446        for (i = 0; i < module_count; ++i) {
 447                switch (topology[i]) {
 448                case MOX_MODULE_SFP:
 449                        if (sfp) {
 450                                printf("Error: Only one SFP module is supported!\n");
 451                        } else if (topaz) {
 452                                printf("Error: SFP module cannot be connected after Topaz Switch module!\n");
 453                        } else {
 454                                sfp_pos = i;
 455                                ++sfp;
 456                        }
 457                        break;
 458                case MOX_MODULE_PCI:
 459                        if (pci)
 460                                printf("Error: Only one Mini-PCIe module is supported!\n");
 461                        else if (usb)
 462                                printf("Error: Mini-PCIe module cannot come after USB 3.0 module!\n");
 463                        else if (i && (i != 1 || !passpci))
 464                                printf("Error: Mini-PCIe module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
 465                        else
 466                                ++pci;
 467                        break;
 468                case MOX_MODULE_TOPAZ:
 469                        if (topaz)
 470                                printf("Error: Only one Topaz module is supported!\n");
 471                        else if (peridot >= 3)
 472                                printf("Error: At most two Peridot modules can come before Topaz module!\n");
 473                        else
 474                                ++topaz;
 475                        break;
 476                case MOX_MODULE_PERIDOT:
 477                        if (sfp || topaz) {
 478                                printf("Error: Peridot module must come before SFP or Topaz module!\n");
 479                        } else if (peridot >= 3) {
 480                                printf("Error: At most three Peridot modules are supported!\n");
 481                        } else {
 482                                peridot_pos[peridot] = i;
 483                                ++peridot;
 484                        }
 485                        break;
 486                case MOX_MODULE_USB3:
 487                        if (pci)
 488                                printf("Error: USB 3.0 module cannot come after Mini-PCIe module!\n");
 489                        else if (usb)
 490                                printf("Error: Only one USB 3.0 module is supported!\n");
 491                        else if (i && (i != 1 || !passpci))
 492                                printf("Error: USB 3.0 module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
 493                        else
 494                                ++usb;
 495                        break;
 496                case MOX_MODULE_PASSPCI:
 497                        if (passpci)
 498                                printf("Error: Only one Passthrough Mini-PCIe module is supported!\n");
 499                        else if (i != 0)
 500                                printf("Error: Passthrough Mini-PCIe module should be the first connected module!\n");
 501                        else
 502                                ++passpci;
 503                }
 504        }
 505
 506        /* now configure modules */
 507
 508        if (get_reset_gpio(&reset_gpio) < 0)
 509                return 0;
 510
 511        if (peridot > 0) {
 512                if (configure_peridots(&reset_gpio) < 0) {
 513                        printf("Cannot configure Peridot modules!\n");
 514                        peridot = 0;
 515                }
 516        } else {
 517                dm_gpio_set_value(&reset_gpio, 1);
 518                mdelay(50);
 519                dm_gpio_set_value(&reset_gpio, 0);
 520                mdelay(50);
 521        }
 522
 523        if (peridot || topaz) {
 524                /*
 525                 * now check if the addresses are set by reading Scratch & Misc
 526                 * register 0x70 of Peridot (and potentially Topaz) modules
 527                 */
 528
 529                bus = miiphy_get_dev_by_name("neta@30000");
 530                if (!bus) {
 531                        printf("Cannot get MDIO bus device!\n");
 532                } else {
 533                        for (i = 0; i < peridot; ++i)
 534                                check_switch_address(bus, 0x10 + i);
 535
 536                        if (topaz)
 537                                check_switch_address(bus, 0x2);
 538
 539                        sw_blink_leds(bus, peridot, topaz);
 540                }
 541        }
 542
 543        printf("\n");
 544
 545        return 0;
 546}
 547
 548#if defined(CONFIG_OF_BOARD_SETUP)
 549
 550static int vnode_by_path(void *blob, const char *fmt, va_list ap)
 551{
 552        char path[128];
 553
 554        vsnprintf(path, 128, fmt, ap);
 555        return fdt_path_offset(blob, path);
 556}
 557
 558static int node_by_path(void *blob, const char *fmt, ...)
 559{
 560        va_list ap;
 561        int res;
 562
 563        va_start(ap, fmt);
 564        res = vnode_by_path(blob, fmt, ap);
 565        va_end(ap);
 566
 567        return res;
 568}
 569
 570static int phandle_by_path(void *blob, const char *fmt, ...)
 571{
 572        va_list ap;
 573        int node, phandle, res;
 574
 575        va_start(ap, fmt);
 576        node = vnode_by_path(blob, fmt, ap);
 577        va_end(ap);
 578
 579        if (node < 0)
 580                return node;
 581
 582        phandle = fdt_get_phandle(blob, node);
 583        if (phandle > 0)
 584                return phandle;
 585
 586        phandle = fdt_get_max_phandle(blob);
 587        if (phandle < 0)
 588                return phandle;
 589
 590        phandle += 1;
 591
 592        res = fdt_setprop_u32(blob, node, "linux,phandle", phandle);
 593        if (res < 0)
 594                return res;
 595
 596        res = fdt_setprop_u32(blob, node, "phandle", phandle);
 597        if (res < 0)
 598                return res;
 599
 600        return phandle;
 601}
 602
 603static int enable_by_path(void *blob, const char *fmt, ...)
 604{
 605        va_list ap;
 606        int node;
 607
 608        va_start(ap, fmt);
 609        node = vnode_by_path(blob, fmt, ap);
 610        va_end(ap);
 611
 612        if (node < 0)
 613                return node;
 614
 615        return fdt_setprop_string(blob, node, "status", "okay");
 616}
 617
 618static bool is_topaz(int id)
 619{
 620        return topaz && id == peridot + topaz - 1;
 621}
 622
 623static int switch_addr(int id)
 624{
 625        return is_topaz(id) ? 0x2 : 0x10 + id;
 626}
 627
 628static int setup_switch(void *blob, int id)
 629{
 630        int res, addr, i, node, phandle;
 631
 632        addr = switch_addr(id);
 633
 634        /* first enable the switch by setting status = "okay" */
 635        res = enable_by_path(blob, MDIO_PATH "/switch%i@%x", id, addr);
 636        if (res < 0)
 637                return res;
 638
 639        /*
 640         * now if there are more switches or a SFP module coming after,
 641         * enable corresponding ports
 642         */
 643        if (id < peridot + topaz - 1) {
 644                res = enable_by_path(blob,
 645                                     MDIO_PATH "/switch%i@%x/ports/port@a",
 646                                     id, addr);
 647        } else if (id == peridot - 1 && !topaz && sfp) {
 648                res = enable_by_path(blob,
 649                                     MDIO_PATH "/switch%i@%x/ports/port-sfp@a",
 650                                     id, addr);
 651        } else {
 652                res = 0;
 653        }
 654        if (res < 0)
 655                return res;
 656
 657        if (id >= peridot + topaz - 1)
 658                return 0;
 659
 660        /* finally change link property if needed */
 661        node = node_by_path(blob, MDIO_PATH "/switch%i@%x/ports/port@a", id,
 662                            addr);
 663        if (node < 0)
 664                return node;
 665
 666        for (i = id + 1; i < peridot + topaz; ++i) {
 667                phandle = phandle_by_path(blob,
 668                                          MDIO_PATH "/switch%i@%x/ports/port@%x",
 669                                          i, switch_addr(i),
 670                                          is_topaz(i) ? 5 : 9);
 671                if (phandle < 0)
 672                        return phandle;
 673
 674                if (i == id + 1)
 675                        res = fdt_setprop_u32(blob, node, "link", phandle);
 676                else
 677                        res = fdt_appendprop_u32(blob, node, "link", phandle);
 678                if (res < 0)
 679                        return res;
 680        }
 681
 682        return 0;
 683}
 684
 685static int remove_disabled_nodes(void *blob)
 686{
 687        while (1) {
 688                int res, offset;
 689
 690                offset = fdt_node_offset_by_prop_value(blob, -1, "status",
 691                                                       "disabled", 9);
 692                if (offset < 0)
 693                        break;
 694
 695                res = fdt_del_node(blob, offset);
 696                if (res < 0)
 697                        return res;
 698        }
 699
 700        return 0;
 701}
 702
 703int ft_board_setup(void *blob, bd_t *bd)
 704{
 705        int node, phandle, res;
 706
 707        /*
 708         * If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are
 709         * connected, enable the PCIe node.
 710         */
 711        if (pci || usb || passpci) {
 712                node = fdt_path_offset(blob, PCIE_PATH);
 713                if (node < 0)
 714                        return node;
 715
 716                res = fdt_setprop_string(blob, node, "status", "okay");
 717                if (res < 0)
 718                        return res;
 719
 720                /* Fix PCIe regions for devices with 4 GB RAM */
 721                res = a3700_fdt_fix_pcie_regions(blob);
 722                if (res < 0)
 723                        return res;
 724        }
 725
 726        /*
 727         * If MOX C (Topaz switch) and/or MOX E (Peridot switch) are connected,
 728         * enable the eth1 node and setup the switches.
 729         */
 730        if (peridot || topaz) {
 731                int i;
 732
 733                res = enable_by_path(blob, ETH1_PATH);
 734                if (res < 0)
 735                        return res;
 736
 737                for (i = 0; i < peridot + topaz; ++i) {
 738                        res = setup_switch(blob, i);
 739                        if (res < 0)
 740                                return res;
 741                }
 742        }
 743
 744        /*
 745         * If MOX D (SFP cage module) is connected, enable the SFP node and eth1
 746         * node. If there is no Peridot switch between MOX A and MOX D, add link
 747         * to the SFP node to eth1 node.
 748         * Also enable and configure SFP GPIO controller node.
 749         */
 750        if (sfp) {
 751                res = enable_by_path(blob, SFP_PATH);
 752                if (res < 0)
 753                        return res;
 754
 755                res = enable_by_path(blob, ETH1_PATH);
 756                if (res < 0)
 757                        return res;
 758
 759                if (!peridot) {
 760                        phandle = phandle_by_path(blob, SFP_PATH);
 761                        if (phandle < 0)
 762                                return res;
 763
 764                        node = node_by_path(blob, ETH1_PATH);
 765                        if (node < 0)
 766                                return node;
 767
 768                        res = fdt_setprop_u32(blob, node, "sfp", phandle);
 769                        if (res < 0)
 770                                return res;
 771
 772                        res = fdt_setprop_string(blob, node, "phy-mode",
 773                                                 "sgmii");
 774                        if (res < 0)
 775                                return res;
 776                }
 777
 778                res = enable_by_path(blob, SFP_GPIO_PATH);
 779                if (res < 0)
 780                        return res;
 781
 782                if (sfp_pos) {
 783                        char newname[16];
 784
 785                        /* moxtet-sfp is on non-zero position, change default */
 786                        node = node_by_path(blob, SFP_GPIO_PATH);
 787                        if (node < 0)
 788                                return node;
 789
 790                        res = fdt_setprop_u32(blob, node, "reg", sfp_pos);
 791                        if (res < 0)
 792                                return res;
 793
 794                        sprintf(newname, "gpio@%x", sfp_pos);
 795
 796                        res = fdt_set_name(blob, node, newname);
 797                        if (res < 0)
 798                                return res;
 799                }
 800        }
 801
 802        fdt_fixup_ethernet(blob);
 803
 804        /* Finally remove disabled nodes, as per Rob Herring's request. */
 805        remove_disabled_nodes(blob);
 806
 807        return 0;
 808}
 809
 810#endif
 811