1 // SPDX-License-Identifier: GPL-2.0+
3 * Traverse Ten64 Family board
4 * Copyright 2017-2018 NXP
5 * Copyright 2019-2021 Traverse Technologies
8 #include <display_options.h>
21 #include <asm/global_data.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>
31 #include <asm/arch/fsl_serdes.h>
32 #include <asm/arch/soc.h>
33 #include <asm/arch-fsl-layerscape/fsl_icid.h>
36 #include <fsl_immap.h>
38 #include "../common/ten64-controller.h"
40 #define I2C_RETIMER_ADDR 0x27
42 DECLARE_GLOBAL_DATA_PTR;
44 static int ten64_read_board_info(struct t64uc_board_info *);
45 static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *);
46 static void ten64_board_retimer_ds110df410_init(void);
49 TEN64_BOARD_REV_A = 0xFF,
50 TEN64_BOARD_REV_B = 0xFE,
51 TEN64_BOARD_REV_C = 0xFD,
52 TEN64_BOARD_REV_D = 0xFC,
56 #define RESV_MEM_IN_BANK(b) (gd->arch.resv_ram >= base[b] && \
57 gd->arch.resv_ram < base[b] + size[b])
59 int board_early_init_f(void)
61 fsl_lsch3_early_init_f();
65 static u32 ten64_get_board_rev(void)
67 struct ccsr_gur *dcfg = (void *)CFG_SYS_FSL_GUTS_ADDR;
68 u32 board_rev_in = in_le32(&dcfg->gpporcr1);
74 enum boot_src src = get_boot_src();
76 struct t64uc_board_info boardinfo;
77 u32 board_rev = ten64_get_board_rev();
80 case TEN64_BOARD_REV_A:
81 snprintf(boardmodel, 32, "A (Alpha)");
83 case TEN64_BOARD_REV_B:
84 snprintf(boardmodel, 32, "B (Beta)");
86 case TEN64_BOARD_REV_C:
87 snprintf(boardmodel, 32, "C");
89 case TEN64_BOARD_REV_D:
90 snprintf(boardmodel, 32, "D");
93 snprintf(boardmodel, 32, " Revision %X", (0xFF - board_rev));
97 printf("Board: 1064-0201%s, boot from ", boardmodel);
99 if (src == BOOT_SOURCE_SD_MMC)
101 else if (src == BOOT_SOURCE_QSPI_NOR)
104 printf("Unknown boot source %d\n", src);
106 puts("Controller: ");
107 if (IS_ENABLED(CONFIG_TEN64_CONTROLLER)) {
108 /* Driver not compatible with alpha/beta board MCU firmware */
109 if (board_rev <= TEN64_BOARD_REV_C) {
110 if (ten64_read_board_info(&boardinfo)) {
111 puts("ERROR: unable to communicate\n");
113 printf("firmware %d.%d.%d\n",
114 boardinfo.fwversion_major,
115 boardinfo.fwversion_minor,
116 boardinfo.fwversion_patch);
117 ten64_set_macaddrs_from_board_info(&boardinfo);
120 puts("not supported on this board revision\n");
123 puts("driver not enabled (no MAC addresses or other information will be read)\n");
131 init_final_memctl_regs();
133 if (IS_ENABLED(CONFIG_FSL_CAAM))
139 int fsl_initdram(void)
141 gd->ram_size = tfa_get_dram_size();
144 gd->ram_size = fsl_ddr_sdram_size();
149 void detail_board_ddr_info(void)
152 print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
156 void board_quiesce_devices(void)
158 if (IS_ENABLED(CONFIG_FSL_MC_ENET))
159 fsl_mc_ldpaa_exit(gd->bd);
162 void fdt_fixup_board_enet(void *fdt)
166 offset = fdt_path_offset(fdt, "/fsl-mc");
169 offset = fdt_path_offset(fdt, "/soc/fsl-mc");
172 printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
177 if (get_mc_boot_status() == 0 &&
178 (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0))
179 fdt_status_okay(fdt, offset);
181 fdt_status_fail(fdt, offset);
184 /* Called after SoC board_late_init in fsl-layerscape/soc.c */
185 int fsl_board_late_init(void)
187 ten64_board_retimer_ds110df410_init();
189 /* Ensure nvme storage devices are available to bootflow */
190 if (IS_ENABLED(CONFIG_NVME))
191 nvme_scan_namespace();
196 int ft_board_setup(void *blob, struct bd_info *bd)
199 u16 mc_memory_bank = 0;
203 u64 mc_memory_base = 0;
204 u64 mc_memory_size = 0;
205 u16 total_memory_banks;
207 debug("%s blob=0x%p\n", __func__, blob);
209 ft_cpu_setup(blob, bd);
211 fdt_fixup_mc_ddr(&mc_memory_base, &mc_memory_size);
213 if (mc_memory_base != 0)
216 total_memory_banks = CONFIG_NR_DRAM_BANKS + mc_memory_bank;
218 base = calloc(total_memory_banks, sizeof(u64));
219 size = calloc(total_memory_banks, sizeof(u64));
221 /* fixup DT for the two GPP DDR banks */
222 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
223 base[i] = gd->bd->bi_dram[i].start;
224 size[i] = gd->bd->bi_dram[i].size;
225 /* reduce size if reserved memory is within this bank */
226 if (IS_ENABLED(CONFIG_RESV_RAM) && RESV_MEM_IN_BANK(i))
227 size[i] = gd->arch.resv_ram - base[i];
230 if (mc_memory_base != 0) {
231 for (i = 0; i <= total_memory_banks; i++) {
232 if (base[i] == 0 && size[i] == 0) {
233 base[i] = mc_memory_base;
234 size[i] = mc_memory_size;
240 fdt_fixup_memory_banks(blob, base, size, total_memory_banks);
242 fdt_fsl_mc_fixup_iommu_map_entry(blob);
244 if (IS_ENABLED(CONFIG_FSL_MC_ENET))
245 fdt_fixup_board_enet(blob);
247 fdt_fixup_icid(blob);
252 #define MACADDRBITS(a, b) (u8)(((a) >> (b)) & 0xFF)
254 /** Probe and return a udevice for the Ten64 board microcontroller.
255 * Optionally, return the I2C bus the microcontroller resides on
256 * @i2c_bus_out: return I2C bus device handle in this pointer
258 static int ten64_get_micro_udevice(struct udevice **ucdev, struct udevice **i2c_bus_out)
261 struct udevice *i2cbus;
263 ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus);
265 printf("%s: Could not get I2C UCLASS", __func__);
269 *i2c_bus_out = i2cbus;
271 ret = dm_i2c_probe(i2cbus, 0x7E, DM_I2C_CHIP_RD_ADDRESS, ucdev);
273 printf("%s: Could not get microcontroller device\n", __func__);
279 static int ten64_read_board_info(struct t64uc_board_info *boardinfo)
281 struct udevice *ucdev;
284 ret = ten64_get_micro_udevice(&ucdev, NULL);
288 ret = misc_call(ucdev, TEN64_CNTRL_GET_BOARD_INFO, NULL, 0, (void *)boardinfo, 0);
295 static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *boardinfo)
299 u8 intfidx, this_dpmac_num;
301 /* We will copy the MAC address returned from the
302 * uC (48 bits) into the u64 macaddr
304 u8 *macaddr_bytes = (u8 *)&macaddr + 2;
306 /** MAC addresses are allocated in order of the physical port numbers,
307 * DPMAC7->10 is "eth0" through "eth3"
308 * DPMAC3->6 is "eth4" through "eth7"
309 * DPMAC2 and 1 are "eth8" and "eth9" respectively
311 int allocation_order[10] = {7, 8, 9, 10, 3, 4, 5, 6, 2, 1};
313 memcpy(macaddr_bytes, boardinfo->mac, 6);
314 /* MAC address bytes from uC are in big endian,
317 macaddr = __be64_to_cpu(macaddr);
319 for (intfidx = 0; intfidx < 10; intfidx++) {
320 snprintf(ethaddr, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
321 MACADDRBITS(macaddr, 40),
322 MACADDRBITS(macaddr, 32),
323 MACADDRBITS(macaddr, 24),
324 MACADDRBITS(macaddr, 16),
325 MACADDRBITS(macaddr, 8),
326 MACADDRBITS(macaddr, 0));
328 this_dpmac_num = allocation_order[intfidx];
329 printf("DPMAC%d: %s\n", this_dpmac_num, ethaddr);
330 snprintf(enetvar, 10,
331 (intfidx != 0) ? "eth%daddr" : "ethaddr",
335 if (!env_get(enetvar))
336 env_set(enetvar, ethaddr);
340 /* The retimer (DS110DF410) is one of the devices without
341 * a RESET line, but a power switch is on the board
342 * allowing it to be reset via uC command
344 static int board_cycle_retimer(struct udevice **retim_dev)
348 struct udevice *uc_dev;
349 struct udevice *i2cbus;
350 u32 board_rev = ten64_get_board_rev();
352 ret = ten64_get_micro_udevice(&uc_dev, &i2cbus);
356 /* Retimer power cycle not implemented on early board
357 * revisions/controller firmwares
359 if (IS_ENABLED(CONFIG_TEN64_CONTROLLER) &&
360 board_rev <= TEN64_BOARD_REV_C) {
361 ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev);
363 puts("(retimer on, resetting...) ");
365 ret = misc_call(uc_dev, TEN64_CNTRL_10G_OFF, NULL, 0, NULL, 0);
369 ret = misc_call(uc_dev, TEN64_CNTRL_10G_ON, NULL, 0, NULL, 0);
372 // Wait for retimer to come back
373 for (loop = 0; loop < 5; loop++) {
374 ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev);
383 /* ten64_board_retimer_ds110df410_init() - Configure the 10G retimer
384 * Adopted from the t102xqds board file
386 static void ten64_board_retimer_ds110df410_init(void)
390 struct udevice *retim_dev;
394 ret = board_cycle_retimer(&retim_dev);
396 puts("Retimer power on failed\n");
400 /* Access to Control/Shared register */
403 ret = dm_i2c_write(retim_dev, 0xff, ®, 1);
405 printf("Error writing to retimer register (error %d)\n", ret);
409 /* Read device revision and ID */
410 dm_i2c_read(retim_dev, 1, ®, 1);
412 puts("DS110DF410 found\n");
414 printf("Unknown retimer 0x%xn\n", reg);
416 /* Enable Broadcast */
418 dm_i2c_write(retim_dev, 0xff, ®, 1);
420 /* Perform a full reset (state, channel and clock)
422 * as the DS110DF410 does not have a RESET line
424 dm_i2c_read(retim_dev, 0, ®, 1);
426 dm_i2c_write(retim_dev, 0, ®, 1);
428 /* Set rate/subrate = 0 */
430 dm_i2c_write(retim_dev, 0x2F, ®, 1);
432 /* Set data rate as 10.3125 Gbps */
434 dm_i2c_write(retim_dev, 0x60, ®, 1);
436 dm_i2c_write(retim_dev, 0x61, ®, 1);
438 dm_i2c_write(retim_dev, 0x62, ®, 1);
440 dm_i2c_write(retim_dev, 0x63, ®, 1);
442 dm_i2c_write(retim_dev, 0x64, ®, 1);
444 /* Invert channel 2 (Lower SFP TX to CPU) due to the SFP being inverted */
446 dm_i2c_write(retim_dev, 0xFF, ®, 1);
447 dm_i2c_read(retim_dev, 0x1F, ®, 1);
449 dm_i2c_write(retim_dev, 0x1F, ®, 1);