global: Migrate CONFIG_SYS_FSL* symbols to the CFG_SYS namespace
[platform/kernel/u-boot.git] / board / traverse / ten64 / ten64.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Traverse Ten64 Family board
4  * Copyright 2017-2018 NXP
5  * Copyright 2019-2021 Traverse Technologies
6  */
7 #include <common.h>
8 #include <display_options.h>
9 #include <dm/uclass.h>
10 #include <env.h>
11 #include <i2c.h>
12 #include <init.h>
13 #include <log.h>
14 #include <malloc.h>
15 #include <errno.h>
16 #include <misc.h>
17 #include <netdev.h>
18 #include <fsl_ifc.h>
19 #include <fsl_ddr.h>
20 #include <fsl_sec.h>
21 #include <asm/global_data.h>
22 #include <asm/io.h>
23 #include <fdt_support.h>
24 #include <linux/delay.h>
25 #include <linux/libfdt.h>
26 #include <fsl-mc/fsl_mc.h>
27 #include <env_internal.h>
28 #include <asm/arch-fsl-layerscape/soc.h>
29 #include <asm/arch/ppa.h>
30 #include <hwconfig.h>
31 #include <asm/arch/fsl_serdes.h>
32 #include <asm/arch/soc.h>
33 #include <asm/arch-fsl-layerscape/fsl_icid.h>
34
35 #include <fsl_immap.h>
36
37 #include "../common/ten64-controller.h"
38
39 #define I2C_RETIMER_ADDR                0x27
40
41 DECLARE_GLOBAL_DATA_PTR;
42
43 static int ten64_read_board_info(struct t64uc_board_info *);
44 static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *);
45 static void ten64_board_retimer_ds110df410_init(void);
46
47 enum {
48         TEN64_BOARD_REV_A = 0xFF,
49         TEN64_BOARD_REV_B = 0xFE,
50         TEN64_BOARD_REV_C = 0xFD
51 };
52
53 #define RESV_MEM_IN_BANK(b)     (gd->arch.resv_ram >= base[b] && \
54                                  gd->arch.resv_ram < base[b] + size[b])
55
56 int board_early_init_f(void)
57 {
58         fsl_lsch3_early_init_f();
59         return 0;
60 }
61
62 static u32 ten64_get_board_rev(void)
63 {
64         struct ccsr_gur *dcfg = (void *)CFG_SYS_FSL_GUTS_ADDR;
65         u32 board_rev_in = in_le32(&dcfg->gpporcr1);
66         return board_rev_in;
67 }
68
69 int checkboard(void)
70 {
71         enum boot_src src = get_boot_src();
72         char boardmodel[32];
73         struct t64uc_board_info boardinfo;
74         u32 board_rev = ten64_get_board_rev();
75
76         switch (board_rev) {
77         case TEN64_BOARD_REV_A:
78                 snprintf(boardmodel, 32, "1064-0201A (Alpha)");
79                 break;
80         case TEN64_BOARD_REV_B:
81                 snprintf(boardmodel, 32, "1064-0201B (Beta)");
82                 break;
83         case TEN64_BOARD_REV_C:
84                 snprintf(boardmodel, 32, "1064-0201C");
85                 break;
86         default:
87                 snprintf(boardmodel, 32, "1064 Revision %X", (0xFF - board_rev));
88                 break;
89         }
90
91         printf("Board: %s, boot from ", boardmodel);
92         if (src == BOOT_SOURCE_SD_MMC)
93                 puts("SD card\n");
94         else if (src == BOOT_SOURCE_QSPI_NOR)
95                 puts("QSPI\n");
96         else
97                 printf("Unknown boot source %d\n", src);
98
99         puts("Controller: ");
100         if (CONFIG_IS_ENABLED(TEN64_CONTROLLER)) {
101                 /* Driver not compatible with alpha/beta board MCU firmware */
102                 if (board_rev <= TEN64_BOARD_REV_C) {
103                         if (ten64_read_board_info(&boardinfo)) {
104                                 puts("ERROR: unable to communicate\n");
105                         } else {
106                                 printf("firmware %d.%d.%d\n",
107                                        boardinfo.fwversion_major,
108                                        boardinfo.fwversion_minor,
109                                        boardinfo.fwversion_patch);
110                                 ten64_set_macaddrs_from_board_info(&boardinfo);
111                         }
112                 } else {
113                         puts("not supported on this board revision\n");
114                 }
115         } else {
116                 puts("driver not enabled (no MAC addresses or other information will be read)\n");
117         }
118
119         return 0;
120 }
121
122 int board_init(void)
123 {
124         init_final_memctl_regs();
125
126         if (CONFIG_IS_ENABLED(FSL_CAAM))
127                 sec_init();
128
129         return 0;
130 }
131
132 int fsl_initdram(void)
133 {
134         gd->ram_size = tfa_get_dram_size();
135
136         if (!gd->ram_size)
137                 gd->ram_size = fsl_ddr_sdram_size();
138
139         return 0;
140 }
141
142 void detail_board_ddr_info(void)
143 {
144         puts("\nDDR    ");
145         print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
146         print_ddr_info(0);
147 }
148
149 void board_quiesce_devices(void)
150 {
151         if (IS_ENABLED(CONFIG_FSL_MC_ENET))
152                 fsl_mc_ldpaa_exit(gd->bd);
153 }
154
155 void fdt_fixup_board_enet(void *fdt)
156 {
157         int offset;
158
159         offset = fdt_path_offset(fdt, "/fsl-mc");
160
161         if (offset < 0)
162                 offset = fdt_path_offset(fdt, "/soc/fsl-mc");
163
164         if (offset < 0) {
165                 printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
166                        __func__, offset);
167                 return;
168         }
169
170         if (get_mc_boot_status() == 0 &&
171             (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0))
172                 fdt_status_okay(fdt, offset);
173         else
174                 fdt_status_fail(fdt, offset);
175 }
176
177 /* Called after SoC board_late_init in fsl-layerscape/soc.c */
178 int fsl_board_late_init(void)
179 {
180         ten64_board_retimer_ds110df410_init();
181         return 0;
182 }
183
184 int ft_board_setup(void *blob, struct bd_info *bd)
185 {
186         int i;
187         u16 mc_memory_bank = 0;
188
189         u64 *base;
190         u64 *size;
191         u64 mc_memory_base = 0;
192         u64 mc_memory_size = 0;
193         u16 total_memory_banks;
194
195         debug("%s blob=0x%p\n", __func__, blob);
196
197         ft_cpu_setup(blob, bd);
198
199         fdt_fixup_mc_ddr(&mc_memory_base, &mc_memory_size);
200
201         if (mc_memory_base != 0)
202                 mc_memory_bank++;
203
204         total_memory_banks = CONFIG_NR_DRAM_BANKS + mc_memory_bank;
205
206         base = calloc(total_memory_banks, sizeof(u64));
207         size = calloc(total_memory_banks, sizeof(u64));
208
209         /* fixup DT for the two GPP DDR banks */
210         for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
211                 base[i] = gd->bd->bi_dram[i].start;
212                 size[i] = gd->bd->bi_dram[i].size;
213                 /* reduce size if reserved memory is within this bank */
214                 if (CONFIG_IS_ENABLED(RESV_RAM) && RESV_MEM_IN_BANK(i))
215                         size[i] = gd->arch.resv_ram - base[i];
216         }
217
218         if (mc_memory_base != 0) {
219                 for (i = 0; i <= total_memory_banks; i++) {
220                         if (base[i] == 0 && size[i] == 0) {
221                                 base[i] = mc_memory_base;
222                                 size[i] = mc_memory_size;
223                                 break;
224                         }
225                 }
226         }
227
228         fdt_fixup_memory_banks(blob, base, size, total_memory_banks);
229
230         fdt_fsl_mc_fixup_iommu_map_entry(blob);
231
232         if (CONFIG_IS_ENABLED(FSL_MC_ENET))
233                 fdt_fixup_board_enet(blob);
234
235         fdt_fixup_icid(blob);
236
237         return 0;
238 }
239
240 #define MACADDRBITS(a, b) (u8)(((a) >> (b)) & 0xFF)
241
242 /** Probe and return a udevice for the Ten64 board microcontroller.
243  * Optionally, return the I2C bus the microcontroller resides on
244  * @i2c_bus_out: return I2C bus device handle in this pointer
245  */
246 static int ten64_get_micro_udevice(struct udevice **ucdev, struct udevice **i2c_bus_out)
247 {
248         int ret;
249         struct udevice *i2cbus;
250
251         ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus);
252         if (ret) {
253                 printf("%s: Could not get I2C UCLASS", __func__);
254                 return ret;
255         }
256         if (i2c_bus_out)
257                 *i2c_bus_out = i2cbus;
258
259         ret = dm_i2c_probe(i2cbus, 0x7E, DM_I2C_CHIP_RD_ADDRESS, ucdev);
260         if (ret) {
261                 printf("%s: Could not get microcontroller device\n", __func__);
262                 return ret;
263         }
264         return ret;
265 }
266
267 static int ten64_read_board_info(struct t64uc_board_info *boardinfo)
268 {
269         struct udevice *ucdev;
270         int ret;
271
272         ret = ten64_get_micro_udevice(&ucdev, NULL);
273         if (ret)
274                 return ret;
275
276         ret = misc_call(ucdev, TEN64_CNTRL_GET_BOARD_INFO, NULL, 0, (void *)boardinfo, 0);
277         if (ret)
278                 return ret;
279
280         return 0;
281 }
282
283 static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *boardinfo)
284 {
285         char ethaddr[18];
286         char enetvar[10];
287         u8 intfidx, this_dpmac_num;
288         u64 macaddr = 0;
289         /* We will copy the MAC address returned from the
290          * uC (48 bits) into the u64 macaddr
291          */
292         u8 *macaddr_bytes = (u8 *)&macaddr + 2;
293
294         /** MAC addresses are allocated in order of the physical port numbers,
295          * DPMAC7->10 is "eth0" through "eth3"
296          * DPMAC3->6 is "eth4" through "eth7"
297          * DPMAC2 and 1 are "eth8" and "eth9" respectively
298          */
299         int allocation_order[10] = {7, 8, 9, 10, 3, 4, 5, 6, 2, 1};
300
301         memcpy(macaddr_bytes, boardinfo->mac, 6);
302         /* MAC address bytes from uC are in big endian,
303          * convert to CPU
304          */
305         macaddr = __be64_to_cpu(macaddr);
306
307         for (intfidx = 0; intfidx < 10; intfidx++) {
308                 snprintf(ethaddr, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
309                          MACADDRBITS(macaddr, 40),
310                          MACADDRBITS(macaddr, 32),
311                          MACADDRBITS(macaddr, 24),
312                          MACADDRBITS(macaddr, 16),
313                          MACADDRBITS(macaddr, 8),
314                          MACADDRBITS(macaddr, 0));
315
316                 this_dpmac_num = allocation_order[intfidx];
317                 printf("DPMAC%d: %s\n", this_dpmac_num, ethaddr);
318                 snprintf(enetvar, 10,
319                          (this_dpmac_num != 1) ? "eth%daddr" : "ethaddr",
320                          this_dpmac_num - 1);
321                 macaddr++;
322
323                 if (!env_get(enetvar))
324                         env_set(enetvar, ethaddr);
325         }
326 }
327
328 /* The retimer (DS110DF410) is one of the devices without
329  * a RESET line, but a power switch is on the board
330  * allowing it to be reset via uC command
331  */
332 static int board_cycle_retimer(struct udevice **retim_dev)
333 {
334         int ret;
335         u8 loop;
336         struct udevice *uc_dev;
337         struct udevice *i2cbus;
338
339         ret = ten64_get_micro_udevice(&uc_dev, &i2cbus);
340         if (ret)
341                 return ret;
342
343         ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev);
344         if (ret == 0) {
345                 puts("(retimer on, resetting...) ");
346
347                 ret = misc_call(uc_dev, TEN64_CNTRL_10G_OFF, NULL, 0, NULL, 0);
348                 mdelay(1000);
349         }
350
351         ret = misc_call(uc_dev, TEN64_CNTRL_10G_ON, NULL, 0, NULL, 0);
352
353         // Wait for retimer to come back
354         for (loop = 0; loop < 5; loop++) {
355                 ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev);
356                 if (ret == 0)
357                         return 0;
358                 mdelay(500);
359         }
360
361         return -ENOSYS;
362 }
363
364 /* ten64_board_retimer_ds110df410_init() - Configure the 10G retimer
365  * Adopted from the t102xqds board file
366  */
367 static void ten64_board_retimer_ds110df410_init(void)
368 {
369         u8 reg;
370         int ret;
371         struct udevice *retim_dev;
372         u32 board_rev = ten64_get_board_rev();
373
374         puts("Retimer: ");
375         /* Retimer power cycle not implemented on early board
376          * revisions/controller firmwares
377          */
378         if (CONFIG_IS_ENABLED(TEN64_CONTROLLER) &&
379             board_rev >= TEN64_BOARD_REV_C) {
380                 ret = board_cycle_retimer(&retim_dev);
381                 if (ret) {
382                         puts("Retimer power on failed\n");
383                         return;
384                 }
385         }
386
387         /* Access to Control/Shared register */
388         reg = 0x0;
389
390         ret = dm_i2c_write(retim_dev, 0xff, &reg, 1);
391         if (ret) {
392                 printf("Error writing to retimer register (error %d)\n", ret);
393                 return;
394         }
395
396         /* Read device revision and ID */
397         dm_i2c_read(retim_dev, 1, &reg, 1);
398         if (reg == 0xF0)
399                 puts("DS110DF410 found\n");
400         else
401                 printf("Unknown retimer 0x%xn\n", reg);
402
403         /* Enable Broadcast */
404         reg = 0x0c;
405         dm_i2c_write(retim_dev, 0xff, &reg, 1);
406
407         /* Perform a full reset (state, channel and clock)
408          * for all channels
409          * as the DS110DF410 does not have a RESET line
410          */
411         dm_i2c_read(retim_dev, 0, &reg, 1);
412         reg |= 0x7;
413         dm_i2c_write(retim_dev, 0, &reg, 1);
414
415         /* Set rate/subrate = 0 */
416         reg = 0x6;
417         dm_i2c_write(retim_dev, 0x2F, &reg, 1);
418
419         /* Set data rate as 10.3125 Gbps */
420         reg = 0x0;
421         dm_i2c_write(retim_dev, 0x60, &reg, 1);
422         reg = 0xb2;
423         dm_i2c_write(retim_dev, 0x61, &reg, 1);
424         reg = 0x90;
425         dm_i2c_write(retim_dev, 0x62, &reg, 1);
426         reg = 0xb3;
427         dm_i2c_write(retim_dev, 0x63, &reg, 1);
428         reg = 0xff;
429         dm_i2c_write(retim_dev, 0x64, &reg, 1);
430
431         /* Invert channel 2 (Lower SFP TX to CPU) due to the SFP being inverted */
432         reg = 0x05;
433         dm_i2c_write(retim_dev, 0xFF, &reg, 1);
434         dm_i2c_read(retim_dev, 0x1F, &reg, 1);
435         reg |= 0x80;
436         dm_i2c_write(retim_dev, 0x1F, &reg, 1);
437
438         puts("OK\n");
439 }