blob: dbf71c282e77557e60bfaedf6ea0d1c05ebf7a5a [file] [log] [blame]
/*
* This file is part of the coreboot project.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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 = {
.name = CONFIG_MAINBOARD_PART_NUMBER,
.enable_dev = mainboard_enable,
};