/* SPDX-License-Identifier: GPL-2.0-only */ /* * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0. */ #include <device/device.h> #include <libbdk-hal/bdk-config.h> #include <libbdk-hal/bdk-twsi.h> #include <soc/twsi.h> #include <soc/gpio.h> #include <delay.h> #include <soc/uart.h> #include <console/console.h> #include <soc/clock.h> #include <soc/timer.h> #include <soc/cpu.h> #include <soc/sdram.h> static void mainboard_print_info(void) { printk(BIOS_INFO, "MB: trusted boot : %s\n", gpio_strap_value(10) ? "yes" : "no"); const size_t boot_method = gpio_strap_value(0) | (gpio_strap_value(1) << 1) | (gpio_strap_value(2) << 2) | (gpio_strap_value(3) << 3); printk(BIOS_INFO, "MB: boot method : "); switch (boot_method) { case 0x2: case 0x3: printk(BIOS_INFO, "EMMC\n"); break; case 0x5: case 0x6: printk(BIOS_INFO, "SPI\n"); break; case 0x8: printk(BIOS_INFO, "REMOTE\n"); break; case 0xc: case 0xd: printk(BIOS_INFO, "PCIe\n"); break; default: printk(BIOS_INFO, "unknown\n"); } printk(BIOS_INFO, "MB: REFclk : %llu MHz\n", thunderx_get_ref_clock() / 1000000ULL); printk(BIOS_INFO, "MB: IOclk : %llu MHz\n", thunderx_get_io_clock() / 1000000ULL); printk(BIOS_INFO, "MB: COREclk : %llu MHz\n", thunderx_get_core_clock() / 1000000ULL); printk(BIOS_INFO, "MB: #CPU cores : %zu\n", cpu_get_num_available_cores()); printk(BIOS_INFO, "MB: RAM : %zu MiB\n", sdram_size_mb()); } extern const struct bdk_devicetree_key_value devtree[]; static void mainboard_init(struct device *dev) { size_t i; /* Init timer */ soc_timer_init(); /* Init CPUs */ for (i = 1; i < CONFIG_MAX_CPUS; i++) start_cpu(i, NULL); } static void mainboard_enable(struct device *dev) { dev->ops->init = &mainboard_init; bdk_config_set_fdt(devtree); /* * Adapted from Cavium's devicetree TWSI-WRITE: * Init board-specific I2C hardware: */ twsi_init(0, I2C_SPEED_STANDARD); /* Initialize IO expander U6 to power-up defaults */ /* float all pins 0.0-0.7 */ bdk_twsix_write_ia(0,0,0x21,6,1,1,0xff); /* float all pins 1.0-1.7 */ bdk_twsix_write_ia(0,0,0x21,7,1,1,0xff); /* 0.x: all outputs low, but disabled */ bdk_twsix_write_ia(0,0,0x21,2,1,1,0x00); /* 1.x: all outputs low, but disabled */ bdk_twsix_write_ia(0,0,0x21,3,1,1,0x00); /* 0.x: no polarity inversion */ bdk_twsix_write_ia(0,0,0x21,4,1,1,0x00); /* 1.x: no polarity inversion */ bdk_twsix_write_ia(0,0,0x21,5,1,1,0x00); /* Initialize IO expander U89 to power-up defaults */ /* float all pins 0.0-0.7 */ bdk_twsix_write_ia(0,0,0x22,6,1,1,0xff); /* float all pins 1.0-1.7 */ bdk_twsix_write_ia(0,0,0x22,7,1,1,0xff); /* 0.x: all outputs low, but disabled */ bdk_twsix_write_ia(0,0,0x22,2,1,1,0x00); /* 1.x: all outputs low, but disabled */ bdk_twsix_write_ia(0,0,0x22,3,1,1,0x00); /* 0.x: no polarity inversion */ bdk_twsix_write_ia(0,0,0x22,4,1,1,0x00); /* 1.x: no polarity inversion */ bdk_twsix_write_ia(0,0,0x22,5,1,1,0x00); /* set outputs SLIC_RESET_L=0 and SPI_SEL=0 */ bdk_twsix_write_ia(0,0,0x21,6,1,1,0xee); /* 0.0 & 0.4 are outputs */ /* Select channel-0 in PCA9546A to enable SFI */ bdk_twsix_write_ia(0, 0, 0x70, 0, 1, 1, 0x7); mdelay(10); /* Configure I2C-GPIO expander I/O directions */ bdk_twsix_write_ia(0, 0, 0x22, 6, 1, 1, 0x07); mdelay(10); /* Configure I2C-GPIO expander I/O directions */ bdk_twsix_write_ia(0, 0, 0x22, 7, 1, 1, 0x38); mdelay(10); /* Turn on SFP+ Transmitters */ bdk_twsix_write_ia(0, 0, 0x22, 2, 1, 1, 0x0); mdelay(10); /* Set VSC7224 to I2C mode */ bdk_twsix_write_ia(0, 0, 0x22, 3, 1, 1, 0x0); mdelay(10); /* Assert VSC7224 reset*/ bdk_twsix_write_ia(0, 0, 0x22, 2, 1, 1, 0x80); mdelay(50); /* Deassert VSC7224 reset*/ bdk_twsix_write_ia(0, 0, 0x22, 2, 1, 1, 0x0); mdelay(50); /* Page select FSYNC0 (0x30) */ bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0030); mdelay(10); /* Set FSYNC0 for 10.3125Gbps See Table 3 */ bdk_twsix_write_ia(0, 0, 0x14, 0x80, 2, 1, 0x2841); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x81, 2, 1, 0x0008); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x82, 2, 1, 0x7a00); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x83, 2, 1, 0x000f); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x84, 2, 1, 0x9c18); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x85, 2, 1, 0x0); mdelay(10); /* All channels Rx settings set equally */ bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0050); mdelay(10); /* Shrink EQ_BUFF */ bdk_twsix_write_ia(0, 0, 0x14, 0x82, 2, 1, 0x0014); mdelay(10); /* Select min DFE Delay (DFE_DELAY) */ bdk_twsix_write_ia(0, 0, 0x14, 0x90, 2, 1, 0x5585); mdelay(10); /* Set DFE 1-3 limit (DXMAX) = 32dec, AP Max limit = 127 decimal */ bdk_twsix_write_ia(0, 0, 0x14, 0x92, 2, 1, 0x207f); mdelay(10); /* Set AP Min limit = 32 decimal */ bdk_twsix_write_ia(0, 0, 0x14, 0x93, 2, 1, 0x2000); mdelay(10); /* Set DFE Averaging to the slowest (DFE_AVG) */ bdk_twsix_write_ia(0, 0, 0x14, 0x94, 2, 1, 0x0031); mdelay(10); /* Set Inductor Bypass OD_IND_BYP = 0 & fastest Rise/Fall */ bdk_twsix_write_ia(0, 0, 0x14, 0x9c, 2, 1, 0x0000); mdelay(10); /* Setting DFE Boost = none. Must set for rev C * (if DFE in adapt mode) */ bdk_twsix_write_ia(0, 0, 0x14, 0xaa, 2, 1, 0x0888); mdelay(10); /* Setting EQ Min/Max = 8/72 */ bdk_twsix_write_ia(0, 0, 0x14, 0xa8, 2, 1, 0x2408); mdelay(10); /* Setting EQVGA = 96, when in EQVGA manual mode */ bdk_twsix_write_ia(0, 0, 0x14, 0xa9, 2, 1, 0x0060); mdelay(10); /* Setting SW_BFOCM, bits 15:14 to 01 */ bdk_twsix_write_ia(0, 0, 0x14, 0x87, 2, 1, 0x4021); mdelay(10); /* Turn off adaptive input equalization and VGA adaptive algorithm * control */ bdk_twsix_write_ia(0, 0, 0x14, 0x89, 2, 1, 0x7313); mdelay(10); /* Turn on adaptive input equalization and VGA adaptive algorithm * control */ bdk_twsix_write_ia(0, 0, 0x14, 0x89, 2, 1, 0x7f13); mdelay(10); /* TAP settings for each channel 0-3 */ /* Ch-0 Tx */ bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0000); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x001f); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x9a, 2, 1, 0x000f); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x9b, 2, 1, 0x0004); mdelay(10); /* Ch-1 Rx */ bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0001); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x1400); mdelay(10); /* Transmitter Output polarity Inverted (Unfortunately, * Rx polarity lines are wrongly inverted on board */ bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x4000); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x000f); mdelay(10); /* Ch-2 Tx */ bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0002); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x001f); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x9a, 2, 1, 0x000f); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x9b, 2, 1, 0x0004); mdelay(10); /* Ch-3 Rx */ bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0003); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x1400); mdelay(10); /* Transmitter Output polarity Inverted (Unfortunately, * Rx polarity lines are wrongly inverted on board */ bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x4000); mdelay(10); bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x000f); mdelay(10); /** * The following hardware magically starts working after toggling * GPIO_10_PHY_RESET_L: * * SATA PHY * * GBE PHY * * XFI PHY * * MMC */ gpio_output(10, 0); udelay(100); gpio_output(10, 1); mainboard_print_info(); } struct chip_operations mainboard_ops = { .enable_dev = mainboard_enable, };