]>
git.ipfire.org Git - thirdparty/u-boot.git/blob - board/CZ.NIC/turris_mox/turris_mox.c
1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Marek BehĂșn <kabel@kernel.org>
7 #include <asm/arch/cpu.h>
8 #include <asm/arch/soc.h>
10 #include <asm/global_data.h>
16 #include <dm/of_extra.h>
18 #include <fdt_support.h>
21 #include <linux/delay.h>
22 #include <linux/libfdt.h>
23 #include <linux/string.h>
29 #define MAX_MOX_MODULES 10
31 #define MOX_MODULE_SFP 0x1
32 #define MOX_MODULE_PCI 0x2
33 #define MOX_MODULE_TOPAZ 0x3
34 #define MOX_MODULE_PERIDOT 0x4
35 #define MOX_MODULE_USB3 0x5
36 #define MOX_MODULE_PASSPCI 0x6
38 #define ARMADA_37XX_NB_GPIO_SEL (MVEBU_REGISTER(0x13830))
39 #define ARMADA_37XX_SPI_CTRL (MVEBU_REGISTER(0x10600))
40 #define ARMADA_37XX_SPI_CFG (MVEBU_REGISTER(0x10604))
41 #define ARMADA_37XX_SPI_DOUT (MVEBU_REGISTER(0x10608))
42 #define ARMADA_37XX_SPI_DIN (MVEBU_REGISTER(0x1060c))
44 DECLARE_GLOBAL_DATA_PTR
;
46 #if defined(CONFIG_OF_BOARD_FIXUP)
47 int board_fix_fdt(void *blob
)
49 enum fdt_status status_pcie
, status_eth1
;
50 u8 topology
[MAX_MOX_MODULES
];
55 * SPI driver is not loaded in driver model yet, but we have to find out
56 * if pcie should be enabled in U-Boot's device tree. Therefore we have
57 * to read SPI by reading/writing SPI registers directly
60 /* put pin from GPIO to SPI mode */
61 clrbits_le32(ARMADA_37XX_NB_GPIO_SEL
, BIT(12));
62 /* configure cpol, cpha, prescale */
63 writel(0x10df, ARMADA_37XX_SPI_CFG
);
66 setbits_le32(ARMADA_37XX_SPI_CTRL
, BIT(17));
68 while (!(readl(ARMADA_37XX_SPI_CTRL
) & 0x2))
71 status_pcie
= FDT_STATUS_DISABLED
;
72 status_eth1
= FDT_STATUS_DISABLED
;
75 for (i
= 0; i
< MAX_MOX_MODULES
; ++i
) {
76 writel(0x0, ARMADA_37XX_SPI_DOUT
);
78 while (!(readl(ARMADA_37XX_SPI_CTRL
) & 0x2))
81 topology
[i
] = readl(ARMADA_37XX_SPI_DIN
) & 0xff;
82 if (topology
[i
] == 0xff)
87 if (topology
[i
] == MOX_MODULE_SFP
&&
88 status_pcie
== FDT_STATUS_DISABLED
)
91 if (topology
[i
] == MOX_MODULE_SFP
||
92 topology
[i
] == MOX_MODULE_TOPAZ
||
93 topology
[i
] == MOX_MODULE_PERIDOT
)
94 status_eth1
= FDT_STATUS_OKAY
;
100 clrbits_le32(ARMADA_37XX_SPI_CTRL
, BIT(17));
102 ret
= fdt_set_status_by_alias(blob
, "ethernet1", status_eth1
);
104 printf("Cannot set status for eth1 in U-Boot's device tree: %s!\n",
108 ret
= fdt_path_offset(blob
, "ethernet1");
110 ret
= fdt_setprop_string(blob
, ret
, "phy-mode", "sgmii");
112 printf("Cannot set phy-mode for eth1 to sgmii in U-Boot device tree: %s!\n",
116 if (size
> 1 && (topology
[1] == MOX_MODULE_PCI
||
117 topology
[1] == MOX_MODULE_USB3
||
118 topology
[1] == MOX_MODULE_PASSPCI
))
119 status_pcie
= FDT_STATUS_OKAY
;
121 ret
= fdt_set_status_by_compatible(blob
, "marvell,armada-3700-pcie",
124 printf("Cannot set status for PCIe in U-Boot's device tree: %s!\n",
129 if (a3700_fdt_fix_pcie_regions(blob
) < 0) {
130 printf("Cannot fix PCIe regions in U-Boot's device tree!\n");
140 /* address of boot parameters */
141 gd
->bd
->bi_boot_params
= CONFIG_SYS_SDRAM_BASE
+ 0x100;
146 static int mox_do_spi(u8
*in
, u8
*out
, size_t size
)
148 struct spi_slave
*slave
;
152 ret
= _spi_get_bus_and_cs(0, 1, 1000000, SPI_CPHA
| SPI_CPOL
,
153 "spi_generic_drv", "moxtet@1", &dev
,
158 ret
= spi_claim_bus(slave
);
162 ret
= spi_xfer(slave
, size
* 8, out
, in
, SPI_XFER_ONCE
);
164 spi_release_bus(slave
);
166 spi_free_slave(slave
);
171 static int mox_get_topology(const u8
**ptopology
, int *psize
, int *pis_sd
)
174 static u8 topology
[MAX_MOX_MODULES
- 1];
176 u8 din
[MAX_MOX_MODULES
], dout
[MAX_MOX_MODULES
];
181 *ptopology
= topology
;
189 memset(din
, 0, MAX_MOX_MODULES
);
190 memset(dout
, 0, MAX_MOX_MODULES
);
192 ret
= mox_do_spi(din
, dout
, MAX_MOX_MODULES
);
198 else if (din
[0] == 0x00)
203 for (i
= 1; i
< MAX_MOX_MODULES
&& din
[i
] != 0xff; ++i
)
204 topology
[i
- 1] = din
[i
] & 0xf;
208 *ptopology
= topology
;
217 #define SW_SMI_CMD_R(d, r) (0x9800 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
218 #define SW_SMI_CMD_W(d, r) (0x9400 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
220 static int sw_multi_read(struct udevice
*bus
, int sw
, int dev
, int reg
)
222 dm_mdio_write(bus
, sw
, MDIO_DEVAD_NONE
, 0, SW_SMI_CMD_R(dev
, reg
));
224 return dm_mdio_read(bus
, sw
, MDIO_DEVAD_NONE
, 1);
227 static void sw_multi_write(struct udevice
*bus
, int sw
, int dev
, int reg
,
230 dm_mdio_write(bus
, sw
, MDIO_DEVAD_NONE
, 1, val
);
231 dm_mdio_write(bus
, sw
, MDIO_DEVAD_NONE
, 0, SW_SMI_CMD_W(dev
, reg
));
235 static int sw_scratch_read(struct udevice
*bus
, int sw
, int reg
)
237 sw_multi_write(bus
, sw
, 0x1c, 0x1a, (reg
& 0x7f) << 8);
238 return sw_multi_read(bus
, sw
, 0x1c, 0x1a) & 0xff;
241 static void sw_led_write(struct udevice
*bus
, int sw
, int port
, int reg
,
244 sw_multi_write(bus
, sw
, port
, 0x16, 0x8000 | ((reg
& 7) << 12)
248 static void sw_blink_leds(struct udevice
*bus
, int peridot
, int topaz
)
256 { 2, 0xef, 1 }, { 2, 0xfe, 1 }, { 2, 0x33, 0 },
257 { 4, 0xef, 1 }, { 4, 0xfe, 1 }, { 4, 0x33, 0 },
258 { 3, 0xfe, 1 }, { 3, 0xef, 1 }, { 3, 0x33, 0 },
259 { 1, 0xfe, 1 }, { 1, 0xef, 1 }, { 1, 0x33, 0 }
262 for (i
= 0; i
< 12; ++i
) {
263 for (p
= 0; p
< peridot
; ++p
) {
264 sw_led_write(bus
, 0x10 + p
, regs
[i
].port
, 0,
266 sw_led_write(bus
, 0x10 + p
, regs
[i
].port
+ 4, 0,
270 sw_led_write(bus
, 0x2, 0x10 + regs
[i
].port
, 0,
279 static void check_switch_address(struct udevice
*bus
, int addr
)
281 if (sw_scratch_read(bus
, addr
, 0x70) >> 3 != addr
)
282 printf("Check of switch MDIO address failed for 0x%02x\n",
286 static int sfp
, pci
, topaz
, peridot
, usb
, passpci
;
287 static int sfp_pos
, peridot_pos
[3];
288 static int module_count
;
290 static int configure_peridots(struct gpio_desc
*reset_gpio
)
293 u8 dout
[MAX_MOX_MODULES
];
295 memset(dout
, 0, MAX_MOX_MODULES
);
297 /* set addresses of Peridot modules */
298 for (i
= 0; i
< peridot
; ++i
)
299 dout
[module_count
- peridot_pos
[i
]] = (~i
) & 3;
302 * if there is a SFP module connected to the last Peridot module, set
303 * the P10_SMODE to 1 for the Peridot module
306 dout
[module_count
- peridot_pos
[i
- 1]] |= 1 << 3;
308 dm_gpio_set_value(reset_gpio
, 1);
311 ret
= mox_do_spi(NULL
, dout
, module_count
+ 1);
314 dm_gpio_set_value(reset_gpio
, 0);
321 static int get_reset_gpio(struct gpio_desc
*reset_gpio
)
325 node
= fdt_node_offset_by_compatible(gd
->fdt_blob
, 0, "cznic,moxtet");
327 printf("Cannot find Moxtet bus device node!\n");
331 gpio_request_by_name_nodev(offset_to_ofnode(node
), "reset-gpios", 0,
332 reset_gpio
, GPIOD_IS_OUT
);
334 if (!dm_gpio_is_valid(reset_gpio
)) {
335 printf("Cannot find reset GPIO for Moxtet bus!\n");
342 int misc_init_r(void)
347 ret
= mbox_sp_get_board_info(NULL
, mac
[0], mac
[1], NULL
, NULL
);
349 printf("Cannot read data from OTP!\n");
353 for (i
= 0; i
< 2; ++i
) {
356 if (is_valid_ethaddr(mac
[i
]) &&
357 !eth_env_get_enetaddr_by_index("eth", i
, oldmac
))
358 eth_env_set_enetaddr_by_index("eth", i
, mac
[i
]);
364 static void mox_phy_modify(struct phy_device
*phydev
, int page
, int reg
,
369 val
= phydev
->drv
->readext(phydev
, MDIO_DEVAD_NONE
, page
, reg
);
372 phydev
->drv
->writeext(phydev
, MDIO_DEVAD_NONE
, page
, reg
, val
);
375 static void mox_phy_leds_start_blinking(void)
377 struct phy_device
*phydev
;
380 phy_node
= ofnode_get_phy_node(ofnode_path("ethernet0"));
381 if (!ofnode_valid(phy_node
))
384 phydev
= dm_phy_find_by_ofnode(phy_node
);
388 mox_phy_modify(phydev
, 3, 0x12, 0x700, 0x400);
389 mox_phy_modify(phydev
, 3, 0x10, 0xff, 0xbb);
393 printf("Cannot get ethernet PHY!\n");
396 static bool read_reset_button(void)
398 struct udevice
*button
, *led
;
401 if (device_get_global_by_ofnode(
402 ofnode_first_subnode(ofnode_by_compatible(ofnode_null(),
405 printf("Cannot find reset button!\n");
409 if (device_get_global_by_ofnode(
410 ofnode_first_subnode(ofnode_by_compatible(ofnode_null(),
413 printf("Cannot find status LED!\n");
417 led_set_state(led
, LEDST_ON
);
419 for (i
= 0; i
< 21; ++i
) {
420 if (button_get_state(button
) != BUTTON_ON
)
426 led_set_state(led
, LEDST_OFF
);
431 static void handle_reset_button(void)
433 const char * const vars
[1] = { "bootcmd_rescue", };
436 * Ensure that bootcmd_rescue has always stock value, so that running
438 * always works correctly.
440 env_set_default_vars(1, (char * const *)vars
, 0);
442 if (read_reset_button()) {
443 const char * const vars
[2] = {
449 * Set the above envs to their default values, in case the user
450 * managed to break them.
452 env_set_default_vars(2, (char * const *)vars
, 0);
454 /* Ensure bootcmd_rescue is used by distroboot */
455 env_set("boot_targets", "rescue");
457 /* start blinking PHY LEDs */
458 mox_phy_leds_start_blinking();
460 printf("RESET button was pressed, overwriting boot_targets!\n");
463 * In case the user somehow managed to save environment with
464 * boot_targets=rescue, reset boot_targets to default value.
465 * This could happen in subsequent commands if bootcmd_rescue
468 if (!strcmp(env_get("boot_targets"), "rescue")) {
469 const char * const vars
[1] = {
473 env_set_default_vars(1, (char * const *)vars
, 0);
478 int show_board_info(void)
480 int i
, ret
, board_version
, ram_size
, is_sd
;
485 printf("Model: CZ.NIC Turris Mox Board\n");
487 ret
= mbox_sp_get_board_info(&serial_number
, NULL
, NULL
, &board_version
,
490 printf(" Cannot read board info: %i\n", ret
);
492 printf(" Board version: %i\n", board_version
);
493 printf(" RAM size: %i MiB\n", ram_size
);
494 printf(" Serial Number: %016llX\n", serial_number
);
497 pub_key
= mox_sp_get_ecdsa_public_key();
499 printf(" ECDSA Public Key: %s\n", pub_key
);
501 printf(" Cannot read ECDSA Public Key\n");
503 ret
= mox_get_topology(&topology
, &module_count
, &is_sd
);
505 printf("Cannot read module topology!\n");
507 printf(" SD/eMMC version: %s\n", is_sd
? "SD" : "eMMC");
510 printf("Module Topology:\n");
512 for (i
= 0; i
< module_count
; ++i
) {
513 switch (topology
[i
]) {
515 printf("% 4i: SFP Module\n", i
+ 1);
518 printf("% 4i: Mini-PCIe Module\n", i
+ 1);
520 case MOX_MODULE_TOPAZ
:
521 printf("% 4i: Topaz Switch Module (4-port)\n", i
+ 1);
523 case MOX_MODULE_PERIDOT
:
524 printf("% 4i: Peridot Switch Module (8-port)\n", i
+ 1);
526 case MOX_MODULE_USB3
:
527 printf("% 4i: USB 3.0 Module (4 ports)\n", i
+ 1);
529 case MOX_MODULE_PASSPCI
:
530 printf("% 4i: Passthrough Mini-PCIe Module\n", i
+ 1);
533 printf("% 4i: unknown (ID %i)\n", i
+ 1, topology
[i
]);
537 /* check if modules are connected in supported mode */
538 for (i
= 0; i
< module_count
; ++i
) {
539 switch (topology
[i
]) {
542 printf("Error: Only one SFP module is supported!\n");
544 printf("Error: SFP module cannot be connected after Topaz Switch module!\n");
552 printf("Error: Only one Mini-PCIe module is supported!\n");
554 printf("Error: Mini-PCIe module cannot come after USB 3.0 module!\n");
555 else if (i
&& (i
!= 1 || !passpci
))
556 printf("Error: Mini-PCIe module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
560 case MOX_MODULE_TOPAZ
:
562 printf("Error: Only one Topaz module is supported!\n");
563 else if (peridot
>= 3)
564 printf("Error: At most two Peridot modules can come before Topaz module!\n");
568 case MOX_MODULE_PERIDOT
:
570 printf("Error: Peridot module must come before SFP or Topaz module!\n");
571 } else if (peridot
>= 3) {
572 printf("Error: At most three Peridot modules are supported!\n");
574 peridot_pos
[peridot
] = i
;
578 case MOX_MODULE_USB3
:
580 printf("Error: USB 3.0 module cannot come after Mini-PCIe module!\n");
582 printf("Error: Only one USB 3.0 module is supported!\n");
583 else if (i
&& (i
!= 1 || !passpci
))
584 printf("Error: USB 3.0 module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
588 case MOX_MODULE_PASSPCI
:
590 printf("Error: Only one Passthrough Mini-PCIe module is supported!\n");
592 printf("Error: Passthrough Mini-PCIe module should be the first connected module!\n");
601 static struct udevice
*mox_mdio_bus(void)
606 node
= ofnode_by_compatible(ofnode_null(), "marvell,orion-mdio");
607 if (!ofnode_valid(node
))
610 dm_mdio_probe_devices();
612 if (uclass_get_device_by_ofnode(UCLASS_MDIO
, node
, &bus
))
617 printf("Cannot get MDIO bus device!\n");
621 int last_stage_init(void)
623 struct gpio_desc reset_gpio
= {};
625 /* configure modules */
626 if (get_reset_gpio(&reset_gpio
) < 0)
627 goto handle_reset_btn
;
630 if (configure_peridots(&reset_gpio
) < 0) {
631 printf("Cannot configure Peridot modules!\n");
635 dm_gpio_set_value(&reset_gpio
, 1);
637 dm_gpio_set_value(&reset_gpio
, 0);
642 * check if the addresses are set by reading Scratch & Misc register
643 * 0x70 of Peridot (and potentially Topaz) modules
645 if (peridot
|| topaz
) {
646 struct udevice
*bus
= mox_mdio_bus();
651 for (i
= 0; i
< peridot
; ++i
)
652 check_switch_address(bus
, 0x10 + i
);
655 check_switch_address(bus
, 0x2);
657 sw_blink_leds(bus
, peridot
, topaz
);
662 handle_reset_button();
667 #if defined(CONFIG_OF_BOARD_SETUP)
669 static bool is_topaz(int id
)
671 return topaz
&& id
== peridot
+ topaz
- 1;
674 static int switch_addr(int id
)
676 return is_topaz(id
) ? 0x2 : 0x10 + id
;
679 static int setup_switch(void *blob
, int id
)
681 int res
, addr
, i
, node
;
684 node
= fdt_node_offset_by_compatible(blob
, -1, "marvell,orion-mdio");
688 res
= fdt_get_path(blob
, node
, mdio_path
, sizeof(mdio_path
));
692 addr
= switch_addr(id
);
694 /* first enable the switch by setting status = "okay" */
695 res
= fdt_status_okay_by_pathf(blob
, "%s/switch%i@%x", mdio_path
, id
,
701 * now if there are more switches or a SFP module coming after,
702 * enable corresponding ports
704 if (id
< peridot
+ topaz
- 1) {
705 res
= fdt_status_okay_by_pathf(blob
,
706 "%s/switch%i@%x/ports/port@a",
707 mdio_path
, id
, addr
);
708 } else if (id
== peridot
- 1 && !topaz
&& sfp
) {
709 res
= fdt_status_okay_by_pathf(blob
,
710 "%s/switch%i@%x/ports/port-sfp@a",
711 mdio_path
, id
, addr
);
718 if (id
>= peridot
+ topaz
- 1)
721 /* finally change link property if needed */
722 node
= fdt_node_offset_by_pathf(blob
, "%s/switch%i@%x/ports/port@a",
723 mdio_path
, id
, addr
);
727 for (i
= id
+ 1; i
< peridot
+ topaz
; ++i
) {
728 unsigned int phandle
;
730 phandle
= fdt_create_phandle_by_pathf(blob
,
731 "%s/switch%i@%x/ports/port@%x",
734 is_topaz(i
) ? 5 : 9);
736 return -FDT_ERR_NOPHANDLES
;
739 res
= fdt_setprop_u32(blob
, node
, "link", phandle
);
741 res
= fdt_appendprop_u32(blob
, node
, "link", phandle
);
749 int ft_board_setup(void *blob
, struct bd_info
*bd
)
754 * If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are
755 * connected, enable the PCIe node.
757 if (pci
|| usb
|| passpci
) {
758 res
= fdt_status_okay_by_compatible(blob
,
759 "marvell,armada-3700-pcie");
763 /* Fix PCIe regions for devices with 4 GB RAM */
764 res
= a3700_fdt_fix_pcie_regions(blob
);
770 * If MOX C (Topaz switch) and/or MOX E (Peridot switch) are connected,
771 * enable the eth1 node and setup the switches.
773 if (peridot
|| topaz
) {
776 res
= fdt_status_okay_by_alias(blob
, "ethernet1");
780 for (i
= 0; i
< peridot
+ topaz
; ++i
) {
781 res
= setup_switch(blob
, i
);
788 * If MOX D (SFP cage module) is connected, enable the SFP node and eth1
789 * node. If there is no Peridot switch between MOX A and MOX D, add link
790 * to the SFP node to eth1 node.
791 * Also enable and configure SFP GPIO controller node.
796 res
= fdt_status_okay_by_compatible(blob
, "sff,sfp");
800 res
= fdt_status_okay_by_alias(blob
, "ethernet1");
805 unsigned int phandle
;
807 phandle
= fdt_create_phandle_by_compatible(blob
,
810 return -FDT_ERR_NOPHANDLES
;
812 node
= fdt_path_offset(blob
, "ethernet1");
816 res
= fdt_setprop_u32(blob
, node
, "sfp", phandle
);
820 res
= fdt_setprop_string(blob
, node
, "phy-mode",
826 res
= fdt_status_okay_by_compatible(blob
, "cznic,moxtet-gpio");
833 /* moxtet-sfp is on non-zero position, change default */
834 node
= fdt_node_offset_by_compatible(blob
, -1,
835 "cznic,moxtet-gpio");
839 res
= fdt_setprop_u32(blob
, node
, "reg", sfp_pos
);
843 sprintf(newname
, "gpio@%x", sfp_pos
);
845 res
= fdt_set_name(blob
, node
, newname
);
851 fdt_fixup_ethernet(blob
);
853 /* Finally remove disabled nodes, as per Rob Herring's request. */
854 fdt_delete_disabled_nodes(blob
);