1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
11 #include <linux/string.h>
12 #include <linux/libfdt.h>
13 #include <fdt_support.h>
15 #ifdef CONFIG_WDT_ARMADA_37XX
19 #define MAX_MOX_MODULES 10
21 #define MOX_MODULE_SFP 0x1
22 #define MOX_MODULE_PCI 0x2
23 #define MOX_MODULE_TOPAZ 0x3
24 #define MOX_MODULE_PERIDOT 0x4
25 #define MOX_MODULE_USB3 0x5
26 #define MOX_MODULE_PASSPCI 0x6
28 #define ARMADA_37XX_NB_GPIO_SEL 0xd0013830
29 #define ARMADA_37XX_SPI_CTRL 0xd0010600
30 #define ARMADA_37XX_SPI_CFG 0xd0010604
31 #define ARMADA_37XX_SPI_DOUT 0xd0010608
32 #define ARMADA_37XX_SPI_DIN 0xd001060c
34 #define PCIE_PATH "/soc/pcie@d0070000"
36 DECLARE_GLOBAL_DATA_PTR;
38 #if defined(CONFIG_OF_BOARD_FIXUP)
39 int board_fix_fdt(void *blob)
41 u8 topology[MAX_MOX_MODULES];
46 * SPI driver is not loaded in driver model yet, but we have to find out
47 * if pcie should be enabled in U-Boot's device tree. Therefore we have
48 * to read SPI by reading/writing SPI registers directly
51 writel(0x563fa, ARMADA_37XX_NB_GPIO_SEL);
52 writel(0x10df, ARMADA_37XX_SPI_CFG);
53 writel(0x2005b, ARMADA_37XX_SPI_CTRL);
55 while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
58 for (i = 0; i < MAX_MOX_MODULES; ++i) {
59 writel(0x0, ARMADA_37XX_SPI_DOUT);
61 while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
64 topology[i] = readl(ARMADA_37XX_SPI_DIN) & 0xff;
65 if (topology[i] == 0xff)
73 writel(0x5b, ARMADA_37XX_SPI_CTRL);
75 if (size > 1 && (topology[1] == MOX_MODULE_PCI ||
76 topology[1] == MOX_MODULE_USB3 ||
77 topology[1] == MOX_MODULE_PASSPCI))
82 node = fdt_path_offset(blob, PCIE_PATH);
85 printf("Cannot find PCIe node in U-Boot's device tree!\n");
89 if (fdt_setprop_string(blob, node, "status",
90 enable ? "okay" : "disabled") < 0) {
91 printf("Cannot %s PCIe in U-Boot's device tree!\n",
92 enable ? "enable" : "disable");
100 #ifdef CONFIG_WDT_ARMADA_37XX
101 static struct udevice *watchdog_dev;
103 void watchdog_reset(void)
105 static ulong next_reset;
111 now = timer_get_us();
113 /* Do not reset the watchdog too often */
114 if (now > next_reset) {
115 wdt_reset(watchdog_dev);
116 next_reset = now + 100000;
123 /* address of boot parameters */
124 gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
126 #ifdef CONFIG_WDT_ARMADA_37XX
127 if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
128 printf("Cannot find Armada 3720 watchdog!\n");
130 printf("Enabling Armada 3720 watchdog (3 minutes timeout).\n");
131 wdt_start(watchdog_dev, 180000, 0);
138 int last_stage_init(void)
140 struct spi_slave *slave;
142 u8 din[10], dout[10];
145 char module_topology[128];
147 ret = spi_get_bus_and_cs(0, 1, 20000000, SPI_CPHA, "spi_generic_drv",
148 "mox-modules@1", &dev, &slave);
152 ret = spi_claim_bus(slave);
159 ret = spi_xfer(slave, 80, dout, din, SPI_XFER_ONCE);
163 if (din[0] != 0x00 && din[0] != 0xff)
166 printf("Module Topology:\n");
167 for (i = 1; i < 10 && din[i] != 0xff; ++i) {
168 u8 mid = din[i] & 0xf;
170 const char *mname = "";
175 printf("% 4i: SFP Module\n", i);
179 printf("% 4i: Mini-PCIe Module\n", i);
183 printf("% 4i: Topaz Switch Module\n", i);
186 printf("% 4i: unknown (ID %i)\n", i, mid);
189 mlen = strlen(mname);
190 if (len + mlen < sizeof(module_topology)) {
191 strcpy(module_topology + len, mname);
197 module_topology[len > 0 ? len - 1 : 0] = '\0';
199 env_set("module_topology", module_topology);
202 spi_release_bus(slave);
204 spi_free_slave(slave);
207 printf("Cannot read module topology!\n");