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