1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
12 #include <mvebu/comphy.h>
14 #include <linux/string.h>
15 #include <linux/libfdt.h>
16 #include <fdt_support.h>
18 #ifdef CONFIG_WDT_ARMADA_37XX
22 #define MAX_MOX_MODULES 10
24 #define MOX_MODULE_SFP 0x1
25 #define MOX_MODULE_PCI 0x2
26 #define MOX_MODULE_TOPAZ 0x3
27 #define MOX_MODULE_PERIDOT 0x4
28 #define MOX_MODULE_USB3 0x5
29 #define MOX_MODULE_PASSPCI 0x6
31 #define ARMADA_37XX_NB_GPIO_SEL 0xd0013830
32 #define ARMADA_37XX_SPI_CTRL 0xd0010600
33 #define ARMADA_37XX_SPI_CFG 0xd0010604
34 #define ARMADA_37XX_SPI_DOUT 0xd0010608
35 #define ARMADA_37XX_SPI_DIN 0xd001060c
37 #define PCIE_PATH "/soc/pcie@d0070000"
39 DECLARE_GLOBAL_DATA_PTR
;
41 #if defined(CONFIG_OF_BOARD_FIXUP)
42 int board_fix_fdt(void *blob
)
44 u8 topology
[MAX_MOX_MODULES
];
49 * SPI driver is not loaded in driver model yet, but we have to find out
50 * if pcie should be enabled in U-Boot's device tree. Therefore we have
51 * to read SPI by reading/writing SPI registers directly
54 writel(0x563fa, ARMADA_37XX_NB_GPIO_SEL
);
55 writel(0x10df, ARMADA_37XX_SPI_CFG
);
56 writel(0x2005b, ARMADA_37XX_SPI_CTRL
);
58 while (!(readl(ARMADA_37XX_SPI_CTRL
) & 0x2))
61 for (i
= 0; i
< MAX_MOX_MODULES
; ++i
) {
62 writel(0x0, ARMADA_37XX_SPI_DOUT
);
64 while (!(readl(ARMADA_37XX_SPI_CTRL
) & 0x2))
67 topology
[i
] = readl(ARMADA_37XX_SPI_DIN
) & 0xff;
68 if (topology
[i
] == 0xff)
76 writel(0x5b, ARMADA_37XX_SPI_CTRL
);
78 if (size
> 1 && (topology
[1] == MOX_MODULE_PCI
||
79 topology
[1] == MOX_MODULE_USB3
||
80 topology
[1] == MOX_MODULE_PASSPCI
))
85 node
= fdt_path_offset(blob
, PCIE_PATH
);
88 printf("Cannot find PCIe node in U-Boot's device tree!\n");
92 if (fdt_setprop_string(blob
, node
, "status",
93 enable
? "okay" : "disabled") < 0) {
94 printf("Cannot %s PCIe in U-Boot's device tree!\n",
95 enable
? "enable" : "disable");
103 #ifdef CONFIG_WDT_ARMADA_37XX
104 static struct udevice
*watchdog_dev
;
106 void watchdog_reset(void)
108 static ulong next_reset
;
114 now
= timer_get_us();
116 /* Do not reset the watchdog too often */
117 if (now
> next_reset
) {
118 wdt_reset(watchdog_dev
);
119 next_reset
= now
+ 100000;
126 /* address of boot parameters */
127 gd
->bd
->bi_boot_params
= CONFIG_SYS_SDRAM_BASE
+ 0x100;
129 #ifdef CONFIG_WDT_ARMADA_37XX
130 if (uclass_get_device(UCLASS_WDT
, 0, &watchdog_dev
)) {
131 printf("Cannot find Armada 3720 watchdog!\n");
133 printf("Enabling Armada 3720 watchdog (3 minutes timeout).\n");
134 wdt_start(watchdog_dev
, 180000, 0);
141 static int mox_do_spi(u8
*in
, u8
*out
, size_t size
)
143 struct spi_slave
*slave
;
147 ret
= spi_get_bus_and_cs(0, 1, 1000000, SPI_CPHA
| SPI_CPOL
,
148 "spi_generic_drv", "moxtet@1", &dev
,
153 ret
= spi_claim_bus(slave
);
157 ret
= spi_xfer(slave
, size
* 8, out
, in
, SPI_XFER_ONCE
);
159 spi_release_bus(slave
);
161 spi_free_slave(slave
);
166 static int mox_get_topology(const u8
**ptopology
, int *psize
, int *pis_sd
)
169 static u8 topology
[MAX_MOX_MODULES
- 1];
171 u8 din
[MAX_MOX_MODULES
], dout
[MAX_MOX_MODULES
];
176 *ptopology
= topology
;
184 memset(din
, 0, MAX_MOX_MODULES
);
185 memset(dout
, 0, MAX_MOX_MODULES
);
187 ret
= mox_do_spi(din
, dout
, MAX_MOX_MODULES
);
193 else if (din
[0] == 0x00)
198 for (i
= 1; i
< MAX_MOX_MODULES
&& din
[i
] != 0xff; ++i
)
199 topology
[i
- 1] = din
[i
] & 0xf;
203 *ptopology
= topology
;
212 int comphy_update_map(struct comphy_map
*serdes_map
, int count
)
214 int ret
, i
, size
, sfpindex
= -1, swindex
= -1;
217 ret
= mox_get_topology(&topology
, &size
, NULL
);
221 for (i
= 0; i
< size
; ++i
) {
222 if (topology
[i
] == MOX_MODULE_SFP
&& sfpindex
== -1)
224 else if ((topology
[i
] == MOX_MODULE_TOPAZ
||
225 topology
[i
] == MOX_MODULE_PERIDOT
) &&
230 if (sfpindex
>= 0 && swindex
>= 0) {
231 if (sfpindex
< swindex
)
232 serdes_map
[0].speed
= PHY_SPEED_1_25G
;
234 serdes_map
[0].speed
= PHY_SPEED_3_125G
;
235 } else if (sfpindex
>= 0) {
236 serdes_map
[0].speed
= PHY_SPEED_1_25G
;
237 } else if (swindex
>= 0) {
238 serdes_map
[0].speed
= PHY_SPEED_3_125G
;
244 #define SW_SMI_CMD_R(d, r) (0x9800 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
245 #define SW_SMI_CMD_W(d, r) (0x9400 | (((d) & 0x1f) << 5) | ((r) & 0x1f))
247 static int sw_multi_read(struct mii_dev
*bus
, int sw
, int dev
, int reg
)
249 bus
->write(bus
, sw
, 0, 0, SW_SMI_CMD_R(dev
, reg
));
251 return bus
->read(bus
, sw
, 0, 1);
254 static void sw_multi_write(struct mii_dev
*bus
, int sw
, int dev
, int reg
,
257 bus
->write(bus
, sw
, 0, 1, val
);
258 bus
->write(bus
, sw
, 0, 0, SW_SMI_CMD_W(dev
, reg
));
262 static int sw_scratch_read(struct mii_dev
*bus
, int sw
, int reg
)
264 sw_multi_write(bus
, sw
, 0x1c, 0x1a, (reg
& 0x7f) << 8);
265 return sw_multi_read(bus
, sw
, 0x1c, 0x1a) & 0xff;
268 static void sw_led_write(struct mii_dev
*bus
, int sw
, int port
, int reg
,
271 sw_multi_write(bus
, sw
, port
, 0x16, 0x8000 | ((reg
& 7) << 12)
275 static void sw_blink_leds(struct mii_dev
*bus
, int peridot
, int topaz
)
283 { 2, 0xef, 1 }, { 2, 0xfe, 1 }, { 2, 0x33, 0 },
284 { 4, 0xef, 1 }, { 4, 0xfe, 1 }, { 4, 0x33, 0 },
285 { 3, 0xfe, 1 }, { 3, 0xef, 1 }, { 3, 0x33, 0 },
286 { 1, 0xfe, 1 }, { 1, 0xef, 1 }, { 1, 0x33, 0 }
289 for (i
= 0; i
< 12; ++i
) {
290 for (p
= 0; p
< peridot
; ++p
) {
291 sw_led_write(bus
, 0x10 + p
, regs
[i
].port
, 0,
293 sw_led_write(bus
, 0x10 + p
, regs
[i
].port
+ 4, 0,
297 sw_led_write(bus
, 0x2, 0x10 + regs
[i
].port
, 0,
306 static void check_switch_address(struct mii_dev
*bus
, int addr
)
308 if (sw_scratch_read(bus
, addr
, 0x70) >> 3 != addr
)
309 printf("Check of switch MDIO address failed for 0x%02x\n",
313 static int sfp
, pci
, topaz
, peridot
, usb
, passpci
;
314 static int sfp_pos
, peridot_pos
[3];
315 static int module_count
;
317 static int configure_peridots(struct gpio_desc
*reset_gpio
)
320 u8 dout
[MAX_MOX_MODULES
];
322 memset(dout
, 0, MAX_MOX_MODULES
);
324 /* set addresses of Peridot modules */
325 for (i
= 0; i
< peridot
; ++i
)
326 dout
[module_count
- peridot_pos
[i
]] = (~i
) & 3;
329 * if there is a SFP module connected to the last Peridot module, set
330 * the P10_SMODE to 1 for the Peridot module
333 dout
[module_count
- peridot_pos
[i
- 1]] |= 1 << 3;
335 dm_gpio_set_value(reset_gpio
, 1);
338 ret
= mox_do_spi(NULL
, dout
, module_count
+ 1);
341 dm_gpio_set_value(reset_gpio
, 0);
348 static int get_reset_gpio(struct gpio_desc
*reset_gpio
)
352 node
= fdt_node_offset_by_compatible(gd
->fdt_blob
, 0, "cznic,moxtet");
354 printf("Cannot find Moxtet bus device node!\n");
358 gpio_request_by_name_nodev(offset_to_ofnode(node
), "reset-gpios", 0,
359 reset_gpio
, GPIOD_IS_OUT
);
361 if (!dm_gpio_is_valid(reset_gpio
)) {
362 printf("Cannot find reset GPIO for Moxtet bus!\n");
369 int last_stage_init(void)
375 struct gpio_desc reset_gpio
= {};
377 ret
= mox_get_topology(&topology
, &module_count
, &is_sd
);
379 printf("Cannot read module topology!\n");
383 printf("Found Turris Mox %s version\n", is_sd
? "SD" : "eMMC");
384 printf("Module Topology:\n");
385 for (i
= 0; i
< module_count
; ++i
) {
386 switch (topology
[i
]) {
388 printf("% 4i: SFP Module\n", i
+ 1);
391 printf("% 4i: Mini-PCIe Module\n", i
+ 1);
393 case MOX_MODULE_TOPAZ
:
394 printf("% 4i: Topaz Switch Module (4-port)\n", i
+ 1);
396 case MOX_MODULE_PERIDOT
:
397 printf("% 4i: Peridot Switch Module (8-port)\n", i
+ 1);
399 case MOX_MODULE_USB3
:
400 printf("% 4i: USB 3.0 Module (4 ports)\n", i
+ 1);
402 case MOX_MODULE_PASSPCI
:
403 printf("% 4i: Passthrough Mini-PCIe Module\n", i
+ 1);
406 printf("% 4i: unknown (ID %i)\n", i
+ 1, topology
[i
]);
410 /* now check if modules are connected in supported mode */
412 for (i
= 0; i
< module_count
; ++i
) {
413 switch (topology
[i
]) {
416 printf("Error: Only one SFP module is supported!\n");
418 printf("Error: SFP module cannot be connected after Topaz Switch module!\n");
426 printf("Error: Only one Mini-PCIe module is supported!\n");
428 printf("Error: Mini-PCIe module cannot come after USB 3.0 module!\n");
429 } else if (i
&& (i
!= 1 || !passpci
)) {
430 printf("Error: Mini-PCIe module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
435 case MOX_MODULE_TOPAZ
:
437 printf("Error: Only one Topaz module is supported!\n");
438 } else if (peridot
>= 3) {
439 printf("Error: At most two Peridot modules can come before Topaz module!\n");
444 case MOX_MODULE_PERIDOT
:
446 printf("Error: Peridot module must come before SFP or Topaz module!\n");
447 } else if (peridot
>= 3) {
448 printf("Error: At most three Peridot modules are supported!\n");
450 peridot_pos
[peridot
] = i
;
454 case MOX_MODULE_USB3
:
456 printf("Error: USB 3.0 module cannot come after Mini-PCIe module!\n");
458 printf("Error: Only one USB 3.0 module is supported!\n");
459 } else if (i
&& (i
!= 1 || !passpci
)) {
460 printf("Error: USB 3.0 module should be the first connected module or come right after Passthrough Mini-PCIe module!\n");
465 case MOX_MODULE_PASSPCI
:
467 printf("Error: Only one Passthrough Mini-PCIe module is supported!\n");
469 printf("Error: Passthrough Mini-PCIe module should be the first connected module!\n");
476 /* now configure modules */
478 if (get_reset_gpio(&reset_gpio
) < 0)
482 if (configure_peridots(&reset_gpio
) < 0) {
483 printf("Cannot configure Peridot modules!\n");
487 dm_gpio_set_value(&reset_gpio
, 1);
489 dm_gpio_set_value(&reset_gpio
, 0);
493 if (peridot
|| topaz
) {
495 * now check if the addresses are set by reading Scratch & Misc
496 * register 0x70 of Peridot (and potentially Topaz) modules
499 bus
= miiphy_get_dev_by_name("neta@30000");
501 printf("Cannot get MDIO bus device!\n");
503 for (i
= 0; i
< peridot
; ++i
)
504 check_switch_address(bus
, 0x10 + i
);
507 check_switch_address(bus
, 0x2);
509 sw_blink_leds(bus
, peridot
, topaz
);