arm: mvebu: turris_mox: Cosmetic restructurization
[oweals/u-boot.git] / board / CZ.NIC / turris_mox / turris_mox.c
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/io.h>
8 #include <dm.h>
9 #include <clk.h>
10 #include <spi.h>
11 #include <linux/string.h>
12 #include <linux/libfdt.h>
13 #include <fdt_support.h>
14
15 #ifdef CONFIG_WDT_ARMADA_37XX
16 #include <wdt.h>
17 #endif
18
19 #define MAX_MOX_MODULES         10
20
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
27
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
33
34 #define PCIE_PATH       "/soc/pcie@d0070000"
35
36 DECLARE_GLOBAL_DATA_PTR;
37
38 #if defined(CONFIG_OF_BOARD_FIXUP)
39 int board_fix_fdt(void *blob)
40 {
41         u8 topology[MAX_MOX_MODULES];
42         int i, size, node;
43         bool enable;
44
45         /*
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
49          */
50
51         writel(0x563fa, ARMADA_37XX_NB_GPIO_SEL);
52         writel(0x10df, ARMADA_37XX_SPI_CFG);
53         writel(0x2005b, ARMADA_37XX_SPI_CTRL);
54
55         while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
56                 udelay(1);
57
58         for (i = 0; i < MAX_MOX_MODULES; ++i) {
59                 writel(0x0, ARMADA_37XX_SPI_DOUT);
60
61                 while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
62                         udelay(1);
63
64                 topology[i] = readl(ARMADA_37XX_SPI_DIN) & 0xff;
65                 if (topology[i] == 0xff)
66                         break;
67
68                 topology[i] &= 0xf;
69         }
70
71         size = i;
72
73         writel(0x5b, ARMADA_37XX_SPI_CTRL);
74
75         if (size > 1 && (topology[1] == MOX_MODULE_PCI ||
76                          topology[1] == MOX_MODULE_USB3 ||
77                          topology[1] == MOX_MODULE_PASSPCI))
78                 enable = true;
79         else
80                 enable = false;
81
82         node = fdt_path_offset(blob, PCIE_PATH);
83
84         if (node < 0) {
85                 printf("Cannot find PCIe node in U-Boot's device tree!\n");
86                 return 0;
87         }
88
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");
93                 return 0;
94         }
95
96         return 0;
97 }
98 #endif
99
100 #ifdef CONFIG_WDT_ARMADA_37XX
101 static struct udevice *watchdog_dev;
102
103 void watchdog_reset(void)
104 {
105         static ulong next_reset;
106         ulong now;
107
108         if (!watchdog_dev)
109                 return;
110
111         now = timer_get_us();
112
113         /* Do not reset the watchdog too often */
114         if (now > next_reset) {
115                 wdt_reset(watchdog_dev);
116                 next_reset = now + 100000;
117         }
118 }
119 #endif
120
121 int board_init(void)
122 {
123         /* address of boot parameters */
124         gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
125
126 #ifdef CONFIG_WDT_ARMADA_37XX
127         if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) {
128                 printf("Cannot find Armada 3720 watchdog!\n");
129         } else {
130                 printf("Enabling Armada 3720 watchdog (3 minutes timeout).\n");
131                 wdt_start(watchdog_dev, 180000, 0);
132         }
133 #endif
134
135         return 0;
136 }
137
138 static int mox_do_spi(u8 *in, u8 *out, size_t size)
139 {
140         struct spi_slave *slave;
141         struct udevice *dev;
142         int ret;
143
144         ret = spi_get_bus_and_cs(0, 1, 1000000, SPI_CPHA | SPI_CPOL,
145                                  "spi_generic_drv", "moxtet@1", &dev,
146                                  &slave);
147         if (ret)
148                 goto fail;
149
150         ret = spi_claim_bus(slave);
151         if (ret)
152                 goto fail_free;
153
154         ret = spi_xfer(slave, size * 8, out, in, SPI_XFER_ONCE);
155
156         spi_release_bus(slave);
157 fail_free:
158         spi_free_slave(slave);
159 fail:
160         return ret;
161 }
162
163 static int mox_get_topology(const u8 **ptopology, int *psize, int *pis_sd)
164 {
165         static int is_sd;
166         static u8 topology[MAX_MOX_MODULES - 1];
167         static int size;
168         u8 din[MAX_MOX_MODULES], dout[MAX_MOX_MODULES];
169         int ret, i;
170
171         if (size) {
172                 if (ptopology)
173                         *ptopology = topology;
174                 if (psize)
175                         *psize = size;
176                 if (pis_sd)
177                         *pis_sd = is_sd;
178                 return 0;
179         }
180
181         memset(din, 0, MAX_MOX_MODULES);
182         memset(dout, 0, MAX_MOX_MODULES);
183
184         ret = mox_do_spi(din, dout, MAX_MOX_MODULES);
185         if (ret)
186                 return ret;
187
188         if (din[0] == 0x10)
189                 is_sd = 1;
190         else if (din[0] == 0x00)
191                 is_sd = 0;
192         else
193                 return -ENODEV;
194
195         for (i = 1; i < MAX_MOX_MODULES && din[i] != 0xff; ++i)
196                 topology[i - 1] = din[i] & 0xf;
197         size = i - 1;
198
199         if (ptopology)
200                 *ptopology = topology;
201         if (psize)
202                 *psize = size;
203         if (pis_sd)
204                 *pis_sd = is_sd;
205
206         return 0;
207 }
208
209 int last_stage_init(void)
210 {
211         int ret, i;
212         const u8 *topology;
213         int module_count, is_sd;
214
215         ret = mox_get_topology(&topology, &module_count, &is_sd);
216         if (ret) {
217                 printf("Cannot read module topology!\n");
218                 return 0;
219         }
220
221         printf("Found Turris Mox %s version\n", is_sd ? "SD" : "eMMC");
222         printf("Module Topology:\n");
223         for (i = 0; i < module_count; ++i) {
224                 switch (topology[i]) {
225                 case MOX_MODULE_SFP:
226                         printf("% 4i: SFP Module\n", i + 1);
227                         break;
228                 case MOX_MODULE_PCI:
229                         printf("% 4i: Mini-PCIe Module\n", i + 1);
230                         break;
231                 case MOX_MODULE_TOPAZ:
232                         printf("% 4i: Topaz Switch Module (4-port)\n", i + 1);
233                         break;
234                 case MOX_MODULE_PERIDOT:
235                         printf("% 4i: Peridot Switch Module (8-port)\n", i + 1);
236                         break;
237                 case MOX_MODULE_USB3:
238                         printf("% 4i: USB 3.0 Module (4 ports)\n", i + 1);
239                         break;
240                 case MOX_MODULE_PASSPCI:
241                         printf("% 4i: Passthrough Mini-PCIe Module\n", i + 1);
242                         break;
243                 default:
244                         printf("% 4i: unknown (ID %i)\n", i + 1, topology[i]);
245                 }
246         }
247
248         printf("\n");
249
250         return 0;
251 }