1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2018 Marek Beh��n <kabel@kernel.org> 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/global_data.h> 11#include <asm/io.h> 12#include <asm/gpio.h> 13#include <button.h> 14#include <clk.h> 15#include <dm.h> 16#include <dm/of_extra.h> 17#include <env.h> 18#include <env_internal.h> 19#include <event.h> 20#include <fdt_support.h> 21#include <init.h> 22#include <led.h> 23#include <linux/delay.h> 24#include <linux/libfdt.h> 25#include <linux/string.h> 26#include <miiphy.h> 27#include <spi.h> 28#include <spi_flash.h> 29 30#include "mox_sp.h" 31 32#define MAX_MOX_MODULES 10 33 34#define MOX_MODULE_SFP 0x1 35#define MOX_MODULE_PCI 0x2 36#define MOX_MODULE_TOPAZ 0x3 37#define MOX_MODULE_PERIDOT 0x4 38#define MOX_MODULE_USB3 0x5 39#define MOX_MODULE_PASSPCI 0x6 40 41#define ARMADA_37XX_NB_GPIO_SEL (MVEBU_REGISTER(0x13830)) 42#define ARMADA_37XX_SPI_CTRL (MVEBU_REGISTER(0x10600)) 43#define ARMADA_37XX_SPI_CFG (MVEBU_REGISTER(0x10604)) 44#define ARMADA_37XX_SPI_DOUT (MVEBU_REGISTER(0x10608)) 45#define ARMADA_37XX_SPI_DIN (MVEBU_REGISTER(0x1060c)) 46 47DECLARE_GLOBAL_DATA_PTR; 48 49int board_fit_config_name_match(const char *name) 50{ 51 if (!gd->board_type) { 52 enum cznic_a3720_board board; 53 54 if (mbox_sp_get_board_info(NULL, NULL, NULL, NULL, NULL, 55 &board) < 0) { 56 printf("Cannot determine board, defaulting to Turris MOX!\n"); 57 board = BOARD_TURRIS_MOX; 58 } 59 60 gd->board_type = board; 61 } 62 63 return !((gd->board_type == BOARD_TURRIS_MOX && 64 !strcmp(name, "armada-3720-turris-mox")) || 65 (gd->board_type == BOARD_RIPE_ATLAS && 66 !strcmp(name, "armada-3720-ripe-atlas"))); 67} 68 69#if defined(CONFIG_OF_BOARD_FIXUP) 70int board_fix_fdt(void *blob) 71{ 72 enum fdt_status status_pcie, status_eth1; 73 u8 topology[MAX_MOX_MODULES]; 74 int i, size, ret; 75 bool eth1_sgmii; 76 77 if (gd->board_type != BOARD_TURRIS_MOX) 78 return 0; 79 80 /* 81 * SPI driver is not loaded in driver model yet, but we have to find out 82 * if pcie should be enabled in U-Boot's device tree. Therefore we have 83 * to read SPI by reading/writing SPI registers directly 84 */ 85 86 /* put pin from GPIO to SPI mode */ 87 clrbits_le32(ARMADA_37XX_NB_GPIO_SEL, BIT(12)); 88 /* configure cpol, cpha, prescale */ 89 writel(0x10df, ARMADA_37XX_SPI_CFG); 90 mdelay(1); 91 /* enable SPI CS1 */ 92 setbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17)); 93 94 while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2)) 95 udelay(1); 96 97 status_pcie = FDT_STATUS_DISABLED; 98 status_eth1 = FDT_STATUS_DISABLED; 99 eth1_sgmii = false; 100 101 for (i = 0; i < MAX_MOX_MODULES; ++i) { 102 writel(0x0, ARMADA_37XX_SPI_DOUT); 103 104 while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2)) 105 udelay(1); 106 107 topology[i] = readl(ARMADA_37XX_SPI_DIN) & 0xff; 108 if (topology[i] == 0xff) 109 break; 110 111 topology[i] &= 0xf; 112 113 if (topology[i] == MOX_MODULE_SFP && 114 status_pcie == FDT_STATUS_DISABLED) 115 eth1_sgmii = true; 116 117 if (topology[i] == MOX_MODULE_SFP || 118 topology[i] == MOX_MODULE_TOPAZ || 119 topology[i] == MOX_MODULE_PERIDOT) 120 status_eth1 = FDT_STATUS_OKAY; 121 } 122 123 size = i; 124 125 /* disable SPI CS1 */ 126 clrbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17)); 127 128 ret = fdt_set_status_by_alias(blob, "ethernet1", status_eth1); 129 if (ret < 0) 130 printf("Cannot set status for eth1 in U-Boot's device tree: %s!\n", 131 fdt_strerror(ret)); 132 133 if (eth1_sgmii) { 134 ret = fdt_path_offset(blob, "ethernet1"); 135 if (ret >= 0) 136 ret = fdt_setprop_string(blob, ret, "phy-mode", "sgmii"); 137 if (ret < 0) 138 printf("Cannot set phy-mode for eth1 to sgmii in U-Boot device tree: %s!\n", 139 fdt_strerror(ret)); 140 } 141 142 if (size > 1 && (topology[1] == MOX_MODULE_PCI || 143 topology[1] == MOX_MODULE_USB3 || 144 topology[1] == MOX_MODULE_PASSPCI)) 145 status_pcie = FDT_STATUS_OKAY; 146 147 ret = fdt_set_status_by_compatible(blob, "marvell,armada-3700-pcie", 148 status_pcie); 149 if (ret < 0) { 150 printf("Cannot set status for PCIe in U-Boot's device tree: %s!\n", 151 fdt_strerror(ret)); 152 return 0; 153 } 154 155 if (a3700_fdt_fix_pcie_regions(blob) < 0) { 156 printf("Cannot fix PCIe regions in U-Boot's device tree!\n"); 157 return 0; 158 } 159 160 return 0; 161} 162#endif 163 164int board_init(void) 165{ 166 /* address of boot parameters */ 167 gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100; 168 169 return 0; 170} 171 172static int mox_do_spi(u8 *in, u8 *out, size_t size) 173{ 174 struct spi_slave *slave; 175 struct udevice *dev; 176 int ret; 177 178 ret = _spi_get_bus_and_cs(0, 1, 1000000, SPI_CPHA | SPI_CPOL, 179 "spi_generic_drv", "moxtet@1", &dev, 180 &slave); 181 if (ret) 182 goto fail; 183 184 ret = spi_claim_bus(slave); 185 if (ret) 186 goto fail_free; 187 188 ret = spi_xfer(slave, size * 8, out, in, SPI_XFER_ONCE); 189 190 spi_release_bus(slave); 191fail_free: 192 spi_free_slave(slave); 193fail: 194 return ret; 195} 196 197static int mox_get_topology(const u8 **ptopology, int *psize, int *pis_sd) 198{ 199 static int is_sd; 200 static u8 topology[MAX_MOX_MODULES - 1]; 201 static int size; 202 u8 din[MAX_MOX_MODULES], dout[MAX_MOX_MODULES]; 203 int ret, i; 204 205 if (size) { 206 if (ptopology) 207 *ptopology = topology; 208 if (psize) 209 *psize = size; 210 if (pis_sd) 211 *pis_sd = is_sd; 212 return 0; 213 } 214 215 memset(din, 0, MAX_MOX_MODULES); 216 memset(dout, 0, MAX_MOX_MODULES); 217 218 ret = mox_do_spi(din, dout, MAX_MOX_MODULES); 219 if (ret) 220 return ret; 221 222 if (din[0] == 0x10) 223 is_sd = 1; 224 else if (din[0] == 0x00) 225 is_sd = 0; 226 else 227 return -ENODEV; 228 229 for (i = 1; i < MAX_MOX_MODULES && din[i] != 0xff; ++i) 230 topology[i - 1] = din[i] & 0xf; 231 size = i - 1; 232 233 if (ptopology) 234 *ptopology = topology; 235 if (psize) 236 *psize = size; 237 if (pis_sd) 238 *pis_sd = is_sd; 239 240 return 0; 241} 242 243#define SW_SMI_CMD_R(d, r) (0x9800 | (((d) & 0x1f) << 5) | ((r) & 0x1f)) 244#define SW_SMI_CMD_W(d, r) (0x9400 | (((d) & 0x1f) << 5) | ((r) & 0x1f)) 245 246static int sw_multi_read(struct udevice *bus, int sw, int dev, int reg) 247{ 248 dm_mdio_write(bus, sw, MDIO_DEVAD_NONE, 0, SW_SMI_CMD_R(dev, reg)); 249 mdelay(5); 250 return dm_mdio_read(bus, sw, MDIO_DEVAD_NONE, 1); 251} 252 253static void sw_multi_write(struct udevice *bus, int sw, int dev, int reg, 254 u16 val) 255{ 256 dm_mdio_write(bus, sw, MDIO_DEVAD_NONE, 1, val); 257 dm_mdio_write(bus, sw, MDIO_DEVAD_NONE, 0, SW_SMI_CMD_W(dev, reg)); 258 mdelay(5); 259} 260 261static int sw_scratch_read(struct udevice *bus, int sw, int reg) 262{ 263 sw_multi_write(bus, sw, 0x1c, 0x1a, (reg & 0x7f) << 8); 264 return sw_multi_read(bus, sw, 0x1c, 0x1a) & 0xff; 265} 266 267static void sw_led_write(struct udevice *bus, int sw, int port, int reg, 268 u16 val) 269{ 270 sw_multi_write(bus, sw, port, 0x16, 0x8000 | ((reg & 7) << 12) 271 | (val & 0x7ff)); 272} 273 274static void sw_blink_leds(struct udevice *bus, int peridot, int topaz) 275{ 276 int i, p; 277 struct { 278 int port; 279 u16 val; 280 int wait; 281 } regs[] = { 282 { 2, 0xef, 1 }, { 2, 0xfe, 1 }, { 2, 0x33, 0 }, 283 { 4, 0xef, 1 }, { 4, 0xfe, 1 }, { 4, 0x33, 0 }, 284 { 3, 0xfe, 1 }, { 3, 0xef, 1 }, { 3, 0x33, 0 }, 285 { 1, 0xfe, 1 }, { 1, 0xef, 1 }, { 1, 0x33, 0 } 286 }; 287 288 for (i = 0; i < 12; ++i) { 289 for (p = 0; p < peridot; ++p) { 290 sw_led_write(bus, 0x10 + p, regs[i].port, 0, 291 regs[i].val); 292 sw_led_write(bus, 0x10 + p, regs[i].port + 4, 0, 293 regs[i].val); 294 } 295 if (topaz) { 296 sw_led_write(bus, 0x2, 0x10 + regs[i].port, 0, 297 regs[i].val); 298 } 299 300 if (regs[i].wait) 301 mdelay(75); 302 } 303} 304 305static void check_switch_address(struct udevice *bus, int addr) 306{ 307 if (sw_scratch_read(bus, addr, 0x70) >> 3 != addr) 308 printf("Check of switch MDIO address failed for 0x%02x\n", 309 addr); 310} 311 312static int sfp, pci, topaz, peridot, usb, passpci; 313static int sfp_pos, peridot_pos[3]; 314static int module_count; 315 316static int configure_peridots(struct gpio_desc *reset_gpio) 317{ 318 int i, ret; 319 u8 dout[MAX_MOX_MODULES]; 320 321 memset(dout, 0, MAX_MOX_MODULES); 322 323 /* set addresses of Peridot modules */ 324 for (i = 0; i < peridot; ++i) 325 dout[module_count - peridot_pos[i]] = (~i) & 3; 326 327 /* 328 * if there is a SFP module connected to the last Peridot module, set 329 * the P10_SMODE to 1 for the Peridot module 330 */ 331 if (sfp) 332 dout[module_count - peridot_pos[i - 1]] |= 1 << 3; 333 334 dm_gpio_set_value(reset_gpio, 1); 335 mdelay(10); 336 337 ret = mox_do_spi(NULL, dout, module_count + 1); 338 339 mdelay(10); 340 dm_gpio_set_value(reset_gpio, 0); 341 342 mdelay(50); 343 344 return ret; 345} 346 347static int get_reset_gpio(struct gpio_desc *reset_gpio) 348{ 349 int node; 350 351 node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "cznic,moxtet"); 352 if (node < 0) { 353 printf("Cannot find Moxtet bus device node!\n"); 354 return -1; 355 } 356 357 gpio_request_by_name_nodev(offset_to_ofnode(node), "reset-gpios", 0, 358 reset_gpio, GPIOD_IS_OUT); 359 360 if (!dm_gpio_is_valid(reset_gpio)) { 361 printf("Cannot find reset GPIO for Moxtet bus!\n"); 362 return -1; 363 } 364 365 return 0; 366} 367 368/* Load default system DTB binary to $fdr_addr */ 369static void load_spi_dtb(void) 370{ 371 const char *const env_name[1] = { "fdt_addr" }; 372 unsigned long size, offset; 373 struct udevice *spi_dev; 374 struct spi_flash *flash; 375 const char *addr_str; 376 unsigned long addr; 377 void *buf; 378 379 addr_str = env_get(env_name[0]); 380 if (!addr_str) { 381 env_set_default_vars(1, (char * const *)env_name, 0); 382 addr_str = env_get(env_name[0]); 383 } 384 385 if (!addr_str) 386 return; 387 388 addr = hextoul(addr_str, NULL); 389 if (!addr) 390 return; 391 392 spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS, CONFIG_SF_DEFAULT_CS, &spi_dev); 393 flash = dev_get_uclass_priv(spi_dev); 394 if (!flash) 395 return; 396 397 /* 398 * SPI NOR "dtb" partition offset & size hardcoded for now because the 399 * mtd subsystem does not offer finding the partition yet and we do not 400 * want to reimplement OF partition parser here. 401 */ 402 offset = 0x7f0000; 403 size = 0x10000; 404 405 buf = map_physmem(addr, size, MAP_WRBACK); 406 if (!buf) 407 return; 408 409 spi_flash_read(flash, offset, size, buf); 410 unmap_physmem(buf, size); 411} 412 413int misc_init_r(void) 414{ 415 int i, ret, addrcnt; 416 u8 mac[2][6]; 417 418 ret = mbox_sp_get_board_info(NULL, mac[0], mac[1], NULL, NULL, NULL); 419 if (ret < 0) { 420 printf("Cannot read data from OTP!\n"); 421 return 0; 422 } 423 424 if (gd->board_type == BOARD_TURRIS_MOX) 425 addrcnt = 2; 426 else if (gd->board_type == BOARD_RIPE_ATLAS) 427 addrcnt = 1; 428 else 429 addrcnt = 0; 430 431 for (i = 0; i < addrcnt; ++i) { 432 u8 oldmac[6]; 433 434 if (is_valid_ethaddr(mac[i]) && 435 !eth_env_get_enetaddr_by_index("eth", i, oldmac)) 436 eth_env_set_enetaddr_by_index("eth", i, mac[i]); 437 } 438 439 if (gd->board_type == BOARD_RIPE_ATLAS) { 440 env_set("board", "ripe_atlas"); 441 env_set("board_name", "ripe_atlas"); 442 env_set("fdtfile", "marvell/armada-3720-ripe-atlas.dtb"); 443 } else { 444 load_spi_dtb(); 445 } 446 447 return 0; 448} 449 450static void mox_phy_modify(struct phy_device *phydev, int page, int reg, 451 u16 mask, u16 set) 452{ 453 int val; 454 455 val = phydev->drv->readext(phydev, MDIO_DEVAD_NONE, page, reg); 456 val &= ~mask; 457 val |= set; 458 phydev->drv->writeext(phydev, MDIO_DEVAD_NONE, page, reg, val); 459} 460 461static void mox_phy_leds_start_blinking(void) 462{ 463 struct phy_device *phydev; 464 ofnode phy_node; 465 466 phy_node = ofnode_get_phy_node(ofnode_path("ethernet0")); 467 if (!ofnode_valid(phy_node)) 468 goto err; 469 470 phydev = dm_phy_find_by_ofnode(phy_node); 471 if (!phydev) 472 goto err; 473 474 mox_phy_modify(phydev, 3, 0x12, 0x700, 0x400); 475 mox_phy_modify(phydev, 3, 0x10, 0xff, 0xbb); 476 477 return; 478err: 479 printf("Cannot get ethernet PHY!\n"); 480} 481 482static bool read_reset_button(void) 483{ 484 struct udevice *button, *led; 485 int i; 486 487 if (device_get_global_by_ofnode( 488 ofnode_first_subnode(ofnode_by_compatible(ofnode_null(), 489 "gpio-keys")), 490 &button)) { 491 printf("Cannot find reset button!\n"); 492 return false; 493 } 494 495 if (device_get_global_by_ofnode( 496 ofnode_first_subnode(ofnode_by_compatible(ofnode_null(), 497 "gpio-leds")), 498 &led)) { 499 printf("Cannot find status LED!\n"); 500 return false; 501 } 502 503 led_set_state(led, LEDST_ON); 504 505 for (i = 0; i < 21; ++i) { 506 if (button_get_state(button) != BUTTON_ON) 507 return false; 508 if (i < 20) 509 mdelay(50); 510 } 511 512 led_set_state(led, LEDST_OFF); 513 514 return true; 515} 516 517static void handle_reset_button(void) 518{ 519 const char * const vars[1] = { "bootcmd_rescue", }; 520 521 /* 522 * Ensure that bootcmd_rescue has always stock value, so that running 523 * run bootcmd_rescue 524 * always works correctly. 525 */ 526 env_set_default_vars(1, (char * const *)vars, 0); 527 528 if (read_reset_button()) { 529 const char * const vars[3] = { 530 "bootcmd", 531 "bootdelay", 532 "distro_bootcmd", 533 }; 534 535 /* 536 * Set the above envs to their default values, in case the user 537 * managed to break them. 538 */ 539 env_set_default_vars(3, (char * const *)vars, 0); 540 541 /* Ensure bootcmd_rescue is used by distroboot */ 542 env_set("boot_targets", "rescue"); 543 544 /* start blinking PHY LEDs */ 545 mox_phy_leds_start_blinking(); 546 547 printf("RESET button was pressed, overwriting boot_targets!\n"); 548 } else { 549 /* 550 * In case the user somehow managed to save environment with 551 * boot_targets=rescue, reset boot_targets to default value. 552 * This could happen in subsequent commands if bootcmd_rescue 553 * failed. 554 */ 555 if (!strcmp(env_get("boot_targets"), "rescue")) { 556 const char * const vars[1] = { 557 "boot_targets", 558 }; 559 560 env_set_default_vars(1, (char * const *)vars, 0); 561 } 562 } 563} 564 565int checkboard(void) 566{ 567 int i, ret, board_version, ram_size, is_sd; 568 const char *pub_key; 569 const u8 *topology; 570 u64 serial_number; 571 572 ret = mbox_sp_get_board_info(&serial_number, NULL, NULL, &board_version, 573 &ram_size, NULL); 574 if (ret < 0) { 575 printf(" Cannot read board info: %i\n", ret); 576 } else { 577 printf(" Board version: %i\n", board_version); 578 printf(" RAM size: %i MiB\n", ram_size); 579 printf(" Serial Number: %016llX\n", serial_number); 580 } 581 582 pub_key = mox_sp_get_ecdsa_public_key(); 583 if (pub_key) 584 printf(" ECDSA Public Key: %s\n", pub_key); 585 else 586 printf(" Cannot read ECDSA Public Key\n"); 587 588 if (gd->board_type != BOARD_TURRIS_MOX) 589 return 0; 590 591 ret = mox_get_topology(&topology, &module_count, &is_sd); 592 if (ret) 593 printf("Cannot read module topology!\n"); 594 595 printf(" SD/eMMC version: %s\n", is_sd ? "SD" : "eMMC"); 596 597 if (module_count) 598 printf("Module Topology:\n"); 599 600 for (i = 0; i < module_count; ++i) { 601 switch (topology[i]) { 602 case MOX_MODULE_SFP: 603 printf("% 4i: SFP Module\n", i + 1); 604 break; 605 case MOX_MODULE_PCI: 606 printf("% 4i: Mini-PCIe Module\n", i + 1); 607 break; 608 case MOX_MODULE_TOPAZ: 609 printf("% 4i: Topaz Switch Module (4-port)\n", i + 1); 610 break; 611 case MOX_MODULE_PERIDOT: 612 printf("% 4i: Peridot Switch Module (8-port)\n", i + 1); 613 break; 614 case MOX_MODULE_USB3: 615 printf("% 4i: USB 3.0 Module (4 ports)\n", i + 1); 616 break; 617 case MOX_MODULE_PASSPCI: 618 printf("% 4i: Passthrough Mini-PCIe Module\n", i + 1); 619 break; 620 default: 621 printf("% 4i: unknown (ID %i)\n", i + 1, topology[i]); 622 } 623 } 624 625 /* check if modules are connected in supported mode */ 626 for (i = 0; i < module_count; ++i) { 627 switch (topology[i]) { 628 case MOX_MODULE_SFP: 629 if (sfp) { 630 printf("Error: Only one SFP module is supported!\n"); 631 } else if (topaz) { 632 printf("Error: SFP module cannot be connected after Topaz Switch module!\n"); 633 } else { 634 sfp_pos = i; 635 ++sfp; 636 } 637 break; 638 case MOX_MODULE_PCI: 639 if (pci) 640 printf("Error: Only one Mini-PCIe module is supported!\n"); 641 else if (usb) 642 printf("Error: Mini-PCIe module cannot come after USB 3.0 module!\n"); 643 else if (i && (i != 1 || !passpci)) 644 printf("Error: Mini-PCIe module should be the first connected module or come right after Passthrough Mini-PCIe module!\n"); 645 else 646 ++pci; 647 break; 648 case MOX_MODULE_TOPAZ: 649 if (topaz) 650 printf("Error: Only one Topaz module is supported!\n"); 651 else if (peridot >= 3) 652 printf("Error: At most two Peridot modules can come before Topaz module!\n"); 653 else 654 ++topaz; 655 break; 656 case MOX_MODULE_PERIDOT: 657 if (sfp || topaz) { 658 printf("Error: Peridot module must come before SFP or Topaz module!\n"); 659 } else if (peridot >= 3) { 660 printf("Error: At most three Peridot modules are supported!\n"); 661 } else { 662 peridot_pos[peridot] = i; 663 ++peridot; 664 } 665 break; 666 case MOX_MODULE_USB3: 667 if (pci) 668 printf("Error: USB 3.0 module cannot come after Mini-PCIe module!\n"); 669 else if (usb) 670 printf("Error: Only one USB 3.0 module is supported!\n"); 671 else if (i && (i != 1 || !passpci)) 672 printf("Error: USB 3.0 module should be the first connected module or come right after Passthrough Mini-PCIe module!\n"); 673 else 674 ++usb; 675 break; 676 case MOX_MODULE_PASSPCI: 677 if (passpci) 678 printf("Error: Only one Passthrough Mini-PCIe module is supported!\n"); 679 else if (i != 0) 680 printf("Error: Passthrough Mini-PCIe module should be the first connected module!\n"); 681 else 682 ++passpci; 683 } 684 } 685 686 return 0; 687} 688 689static struct udevice *mox_mdio_bus(void) 690{ 691 struct udevice *bus; 692 ofnode node; 693 694 node = ofnode_by_compatible(ofnode_null(), "marvell,orion-mdio"); 695 if (!ofnode_valid(node)) 696 goto err; 697 698 dm_mdio_probe_devices(); 699 700 if (uclass_get_device_by_ofnode(UCLASS_MDIO, node, &bus)) 701 goto err; 702 703 return bus; 704err: 705 printf("Cannot get MDIO bus device!\n"); 706 return NULL; 707} 708 709enum env_location env_get_location(enum env_operation op, int prio) 710{ 711 if (prio > 0) 712 return ENVL_UNKNOWN; 713 714 if (gd->board_type == BOARD_RIPE_ATLAS) 715 return ENVL_MMC; 716 717 return ENVL_SPI_FLASH; 718} 719 720static int last_stage_init(void) 721{ 722 struct gpio_desc reset_gpio = {}; 723 724 if (gd->board_type != BOARD_TURRIS_MOX) 725 return 0; 726 727 /* configure modules */ 728 if (get_reset_gpio(&reset_gpio) < 0) 729 goto handle_reset_btn; 730 731 if (peridot > 0) { 732 if (configure_peridots(&reset_gpio) < 0) { 733 printf("Cannot configure Peridot modules!\n"); 734 peridot = 0; 735 } 736 } else { 737 dm_gpio_set_value(&reset_gpio, 1); 738 mdelay(50); 739 dm_gpio_set_value(&reset_gpio, 0); 740 mdelay(50); 741 } 742 743 /* 744 * check if the addresses are set by reading Scratch & Misc register 745 * 0x70 of Peridot (and potentially Topaz) modules 746 */ 747 if (peridot || topaz) { 748 struct udevice *bus = mox_mdio_bus(); 749 750 if (bus) { 751 int i; 752 753 for (i = 0; i < peridot; ++i) 754 check_switch_address(bus, 0x10 + i); 755 756 if (topaz) 757 check_switch_address(bus, 0x2); 758 759 sw_blink_leds(bus, peridot, topaz); 760 } 761 } 762 763handle_reset_btn: 764 handle_reset_button(); 765 766 return 0; 767} 768EVENT_SPY_SIMPLE(EVT_LAST_STAGE_INIT, last_stage_init); 769 770#if defined(CONFIG_OF_BOARD_SETUP) 771 772static bool is_topaz(int id) 773{ 774 return topaz && id == peridot + topaz - 1; 775} 776 777static int switch_addr(int id) 778{ 779 return is_topaz(id) ? 0x2 : 0x10 + id; 780} 781 782static int setup_switch(void *blob, int id) 783{ 784 int res, addr, i, node; 785 char mdio_path[64]; 786 787 node = fdt_node_offset_by_compatible(blob, -1, "marvell,orion-mdio"); 788 if (node < 0) 789 return node; 790 791 res = fdt_get_path(blob, node, mdio_path, sizeof(mdio_path)); 792 if (res < 0) 793 return res; 794 795 addr = switch_addr(id); 796 797 /* first enable the switch by setting status = "okay" */ 798 res = fdt_status_okay_by_pathf(blob, "%s/switch%i@%x", mdio_path, id, 799 addr); 800 if (res < 0) 801 return res; 802 803 /* 804 * now if there are more switches or a SFP module coming after, 805 * enable corresponding ports 806 */ 807 if (id < peridot + topaz - 1) { 808 res = fdt_status_okay_by_pathf(blob, 809 "%s/switch%i@%x/ports/port@a", 810 mdio_path, id, addr); 811 } else if (id == peridot - 1 && !topaz && sfp) { 812 res = fdt_status_okay_by_pathf(blob, 813 "%s/switch%i@%x/ports/port-sfp@a", 814 mdio_path, id, addr); 815 } else { 816 res = 0; 817 } 818 if (res < 0) 819 return res; 820 821 if (id >= peridot + topaz - 1) 822 return 0; 823 824 /* finally change link property if needed */ 825 node = fdt_node_offset_by_pathf(blob, "%s/switch%i@%x/ports/port@a", 826 mdio_path, id, addr); 827 if (node < 0) 828 return node; 829 830 for (i = id + 1; i < peridot + topaz; ++i) { 831 unsigned int phandle; 832 833 phandle = fdt_create_phandle_by_pathf(blob, 834 "%s/switch%i@%x/ports/port@%x", 835 mdio_path, i, 836 switch_addr(i), 837 is_topaz(i) ? 5 : 9); 838 if (!phandle) 839 return -FDT_ERR_NOPHANDLES; 840 841 if (i == id + 1) 842 res = fdt_setprop_u32(blob, node, "link", phandle); 843 else 844 res = fdt_appendprop_u32(blob, node, "link", phandle); 845 if (res < 0) 846 return res; 847 } 848 849 return 0; 850} 851 852int ft_board_setup(void *blob, struct bd_info *bd) 853{ 854 int res; 855 856 if (gd->board_type != BOARD_TURRIS_MOX) 857 return 0; 858 859 /* 860 * If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are 861 * connected, enable the PCIe node. 862 */ 863 if (pci || usb || passpci) { 864 res = fdt_status_okay_by_compatible(blob, 865 "marvell,armada-3700-pcie"); 866 if (res < 0) 867 return res; 868 869 /* Fix PCIe regions for devices with 4 GB RAM */ 870 res = a3700_fdt_fix_pcie_regions(blob); 871 if (res < 0) 872 return res; 873 } 874 875 /* 876 * If MOX C (Topaz switch) and/or MOX E (Peridot switch) are connected, 877 * enable the eth1 node and setup the switches. 878 */ 879 if (peridot || topaz) { 880 int i; 881 882 res = fdt_status_okay_by_alias(blob, "ethernet1"); 883 if (res < 0) 884 return res; 885 886 for (i = 0; i < peridot + topaz; ++i) { 887 res = setup_switch(blob, i); 888 if (res < 0) 889 return res; 890 } 891 } 892 893 /* 894 * If MOX D (SFP cage module) is connected, enable the SFP node and eth1 895 * node. If there is no Peridot switch between MOX A and MOX D, add link 896 * to the SFP node to eth1 node. 897 * Also enable and configure SFP GPIO controller node. 898 */ 899 if (sfp) { 900 int node; 901 902 res = fdt_status_okay_by_compatible(blob, "sff,sfp"); 903 if (res < 0) 904 return res; 905 906 res = fdt_status_okay_by_alias(blob, "ethernet1"); 907 if (res < 0) 908 return res; 909 910 if (!peridot) { 911 unsigned int phandle; 912 913 phandle = fdt_create_phandle_by_compatible(blob, 914 "sff,sfp"); 915 if (!phandle) 916 return -FDT_ERR_NOPHANDLES; 917 918 node = fdt_path_offset(blob, "ethernet1"); 919 if (node < 0) 920 return node; 921 922 res = fdt_setprop_u32(blob, node, "sfp", phandle); 923 if (res < 0) 924 return res; 925 926 res = fdt_setprop_string(blob, node, "phy-mode", 927 "sgmii"); 928 if (res < 0) 929 return res; 930 931 res = fdt_setprop_string(blob, node, "label", 932 "sfp"); 933 if (res < 0) 934 return res; 935 } 936 937 res = fdt_status_okay_by_compatible(blob, "cznic,moxtet-gpio"); 938 if (res < 0) 939 return res; 940 941 if (sfp_pos) { 942 char newname[16]; 943 944 /* moxtet-sfp is on non-zero position, change default */ 945 node = fdt_node_offset_by_compatible(blob, -1, 946 "cznic,moxtet-gpio"); 947 if (node < 0) 948 return node; 949 950 res = fdt_setprop_u32(blob, node, "reg", sfp_pos); 951 if (res < 0) 952 return res; 953 954 sprintf(newname, "gpio@%x", sfp_pos); 955 956 res = fdt_set_name(blob, node, newname); 957 if (res < 0) 958 return res; 959 } 960 } 961 962 fdt_fixup_ethernet(blob); 963 964 /* Finally remove disabled nodes, as per Rob Herring's request. */ 965 fdt_delete_disabled_nodes(blob); 966 967 return 0; 968} 969 970#endif 971