coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mainboard.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
5  */
6 
7 #include <device/device.h>
8 #include <libbdk-hal/bdk-config.h>
9 #include <libbdk-hal/bdk-twsi.h>
10 #include <soc/twsi.h>
11 #include <soc/gpio.h>
12 #include <delay.h>
13 #include <soc/uart.h>
14 #include <console/console.h>
15 #include <soc/clock.h>
16 #include <soc/timer.h>
17 #include <soc/cpu.h>
18 #include <soc/sdram.h>
19 
20 static void mainboard_print_info(void)
21 {
22  printk(BIOS_INFO, "MB: trusted boot : %s\n",
23  gpio_strap_value(10) ? "yes" : "no");
24 
25  const size_t boot_method = gpio_strap_value(0) |
26  (gpio_strap_value(1) << 1) |
27  (gpio_strap_value(2) << 2) |
28  (gpio_strap_value(3) << 3);
29 
30  printk(BIOS_INFO, "MB: boot method : ");
31  switch (boot_method) {
32  case 0x2:
33  case 0x3:
34  printk(BIOS_INFO, "EMMC\n");
35  break;
36  case 0x5:
37  case 0x6:
38  printk(BIOS_INFO, "SPI\n");
39  break;
40  case 0x8:
41  printk(BIOS_INFO, "REMOTE\n");
42  break;
43  case 0xc:
44  case 0xd:
45  printk(BIOS_INFO, "PCIe\n");
46  break;
47  default:
48  printk(BIOS_INFO, "unknown\n");
49  }
50 
51  printk(BIOS_INFO, "MB: REFclk : %llu MHz\n",
52  thunderx_get_ref_clock() / 1000000ULL);
53 
54  printk(BIOS_INFO, "MB: IOclk : %llu MHz\n",
55  thunderx_get_io_clock() / 1000000ULL);
56 
57  printk(BIOS_INFO, "MB: COREclk : %llu MHz\n",
58  thunderx_get_core_clock() / 1000000ULL);
59 
60  printk(BIOS_INFO, "MB: #CPU cores : %zu\n",
62 
63  printk(BIOS_INFO, "MB: RAM : %zu MiB\n",
64  sdram_size_mb());
65 }
66 
67 extern const struct bdk_devicetree_key_value devtree[];
68 
69 static void mainboard_init(struct device *dev)
70 {
71  size_t i;
72 
73  /* Init timer */
75 
76  /* Init CPUs */
77  for (i = 1; i < CONFIG_MAX_CPUS; i++)
78  start_cpu(i, NULL);
79 }
80 
81 static void mainboard_enable(struct device *dev)
82 {
83  dev->ops->init = &mainboard_init;
84 
85  bdk_config_set_fdt(devtree);
86 
87  /*
88  * Adapted from Cavium's devicetree TWSI-WRITE:
89  * Init board-specific I2C hardware:
90  */
92 
93  /* Initialize IO expander U6 to power-up defaults */
94  /* float all pins 0.0-0.7 */
95  bdk_twsix_write_ia(0,0,0x21,6,1,1,0xff);
96  /* float all pins 1.0-1.7 */
97  bdk_twsix_write_ia(0,0,0x21,7,1,1,0xff);
98  /* 0.x: all outputs low, but disabled */
99  bdk_twsix_write_ia(0,0,0x21,2,1,1,0x00);
100  /* 1.x: all outputs low, but disabled */
101  bdk_twsix_write_ia(0,0,0x21,3,1,1,0x00);
102  /* 0.x: no polarity inversion */
103  bdk_twsix_write_ia(0,0,0x21,4,1,1,0x00);
104  /* 1.x: no polarity inversion */
105  bdk_twsix_write_ia(0,0,0x21,5,1,1,0x00);
106  /* Initialize IO expander U89 to power-up defaults */
107  /* float all pins 0.0-0.7 */
108  bdk_twsix_write_ia(0,0,0x22,6,1,1,0xff);
109  /* float all pins 1.0-1.7 */
110  bdk_twsix_write_ia(0,0,0x22,7,1,1,0xff);
111  /* 0.x: all outputs low, but disabled */
112  bdk_twsix_write_ia(0,0,0x22,2,1,1,0x00);
113  /* 1.x: all outputs low, but disabled */
114  bdk_twsix_write_ia(0,0,0x22,3,1,1,0x00);
115  /* 0.x: no polarity inversion */
116  bdk_twsix_write_ia(0,0,0x22,4,1,1,0x00);
117  /* 1.x: no polarity inversion */
118  bdk_twsix_write_ia(0,0,0x22,5,1,1,0x00);
119  /* set outputs SLIC_RESET_L=0 and SPI_SEL=0 */
120  bdk_twsix_write_ia(0,0,0x21,6,1,1,0xee); /* 0.0 & 0.4 are outputs */
121 
122  /* Select channel-0 in PCA9546A to enable SFI */
123  bdk_twsix_write_ia(0, 0, 0x70, 0, 1, 1, 0x7);
124  mdelay(10);
125  /* Configure I2C-GPIO expander I/O directions */
126  bdk_twsix_write_ia(0, 0, 0x22, 6, 1, 1, 0x07);
127  mdelay(10);
128  /* Configure I2C-GPIO expander I/O directions */
129  bdk_twsix_write_ia(0, 0, 0x22, 7, 1, 1, 0x38);
130  mdelay(10);
131  /* Turn on SFP+ Transmitters */
132  bdk_twsix_write_ia(0, 0, 0x22, 2, 1, 1, 0x0);
133  mdelay(10);
134  /* Set VSC7224 to I2C mode */
135  bdk_twsix_write_ia(0, 0, 0x22, 3, 1, 1, 0x0);
136  mdelay(10);
137  /* Assert VSC7224 reset*/
138  bdk_twsix_write_ia(0, 0, 0x22, 2, 1, 1, 0x80);
139  mdelay(50);
140  /* Deassert VSC7224 reset*/
141  bdk_twsix_write_ia(0, 0, 0x22, 2, 1, 1, 0x0);
142  mdelay(50);
143  /* Page select FSYNC0 (0x30) */
144  bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0030);
145  mdelay(10);
146  /* Set FSYNC0 for 10.3125Gbps See Table 3 */
147  bdk_twsix_write_ia(0, 0, 0x14, 0x80, 2, 1, 0x2841);
148  mdelay(10);
149  bdk_twsix_write_ia(0, 0, 0x14, 0x81, 2, 1, 0x0008);
150  mdelay(10);
151  bdk_twsix_write_ia(0, 0, 0x14, 0x82, 2, 1, 0x7a00);
152  mdelay(10);
153  bdk_twsix_write_ia(0, 0, 0x14, 0x83, 2, 1, 0x000f);
154  mdelay(10);
155  bdk_twsix_write_ia(0, 0, 0x14, 0x84, 2, 1, 0x9c18);
156  mdelay(10);
157  bdk_twsix_write_ia(0, 0, 0x14, 0x85, 2, 1, 0x0);
158  mdelay(10);
159 
160  /* All channels Rx settings set equally */
161  bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0050);
162  mdelay(10);
163  /* Shrink EQ_BUFF */
164  bdk_twsix_write_ia(0, 0, 0x14, 0x82, 2, 1, 0x0014);
165  mdelay(10);
166  /* Select min DFE Delay (DFE_DELAY) */
167  bdk_twsix_write_ia(0, 0, 0x14, 0x90, 2, 1, 0x5585);
168  mdelay(10);
169  /* Set DFE 1-3 limit (DXMAX) = 32dec, AP Max limit = 127 decimal */
170  bdk_twsix_write_ia(0, 0, 0x14, 0x92, 2, 1, 0x207f);
171  mdelay(10);
172  /* Set AP Min limit = 32 decimal */
173  bdk_twsix_write_ia(0, 0, 0x14, 0x93, 2, 1, 0x2000);
174  mdelay(10);
175  /* Set DFE Averaging to the slowest (DFE_AVG) */
176  bdk_twsix_write_ia(0, 0, 0x14, 0x94, 2, 1, 0x0031);
177  mdelay(10);
178  /* Set Inductor Bypass OD_IND_BYP = 0 & fastest Rise/Fall */
179  bdk_twsix_write_ia(0, 0, 0x14, 0x9c, 2, 1, 0x0000);
180  mdelay(10);
181  /* Setting DFE Boost = none. Must set for rev C
182  * (if DFE in adapt mode) */
183  bdk_twsix_write_ia(0, 0, 0x14, 0xaa, 2, 1, 0x0888);
184  mdelay(10);
185  /* Setting EQ Min/Max = 8/72 */
186  bdk_twsix_write_ia(0, 0, 0x14, 0xa8, 2, 1, 0x2408);
187  mdelay(10);
188  /* Setting EQVGA = 96, when in EQVGA manual mode */
189  bdk_twsix_write_ia(0, 0, 0x14, 0xa9, 2, 1, 0x0060);
190  mdelay(10);
191  /* Setting SW_BFOCM, bits 15:14 to 01 */
192  bdk_twsix_write_ia(0, 0, 0x14, 0x87, 2, 1, 0x4021);
193  mdelay(10);
194  /* Turn off adaptive input equalization and VGA adaptive algorithm
195  * control */
196  bdk_twsix_write_ia(0, 0, 0x14, 0x89, 2, 1, 0x7313);
197  mdelay(10);
198  /* Turn on adaptive input equalization and VGA adaptive algorithm
199  * control */
200  bdk_twsix_write_ia(0, 0, 0x14, 0x89, 2, 1, 0x7f13);
201  mdelay(10);
202 
203  /* TAP settings for each channel 0-3 */
204  /* Ch-0 Tx */
205  bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0000);
206  mdelay(10);
207  bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x001f);
208  mdelay(10);
209  bdk_twsix_write_ia(0, 0, 0x14, 0x9a, 2, 1, 0x000f);
210  mdelay(10);
211  bdk_twsix_write_ia(0, 0, 0x14, 0x9b, 2, 1, 0x0004);
212  mdelay(10);
213 
214  /* Ch-1 Rx */
215  bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0001);
216  mdelay(10);
217  bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x1400);
218  mdelay(10);
219  /* Transmitter Output polarity Inverted (Unfortunately,
220  * Rx polarity lines are wrongly inverted on board */
221  bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x4000);
222  mdelay(10);
223  bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x000f);
224  mdelay(10);
225 
226  /* Ch-2 Tx */
227  bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0002);
228  mdelay(10);
229  bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x001f);
230  mdelay(10);
231  bdk_twsix_write_ia(0, 0, 0x14, 0x9a, 2, 1, 0x000f);
232  mdelay(10);
233  bdk_twsix_write_ia(0, 0, 0x14, 0x9b, 2, 1, 0x0004);
234  mdelay(10);
235 
236  /* Ch-3 Rx */
237  bdk_twsix_write_ia(0, 0, 0x14, 0x7f, 2, 1, 0x0003);
238  mdelay(10);
239  bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x1400);
240  mdelay(10);
241  /* Transmitter Output polarity Inverted (Unfortunately,
242  * Rx polarity lines are wrongly inverted on board */
243  bdk_twsix_write_ia(0, 0, 0x14, 0x97, 2, 1, 0x4000);
244  mdelay(10);
245  bdk_twsix_write_ia(0, 0, 0x14, 0x99, 2, 1, 0x000f);
246  mdelay(10);
247 
248  /**
249  * The following hardware magically starts working after toggling
250  * GPIO_10_PHY_RESET_L:
251  * * SATA PHY
252  * * GBE PHY
253  * * XFI PHY
254  * * MMC
255  */
256  gpio_output(10, 0);
257  udelay(100);
258  gpio_output(10, 1);
259 
261 }
262 
265 };
struct chip_operations mainboard_ops
Definition: mainboard.c:19
int bdk_twsix_write_ia(bdk_node_t node, int twsi_id, uint8_t dev_addr, uint16_t internal_addr, int num_bytes, int ia_width_bytes, uint64_t data)
Write 1-8 bytes to a TWSI device using an internal address.
Definition: bdk-coreboot.c:77
static void mainboard_init(struct device *dev)
Definition: mainboard.c:69
const struct bdk_devicetree_key_value devtree[]
Definition: bdk_devicetree.c:8
static void mainboard_print_info(void)
Definition: mainboard.c:20
static void mainboard_enable(struct device *dev)
Definition: mainboard.c:81
size_t sdram_size_mb(void)
Definition: sdram.c:24
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
@ I2C_SPEED_STANDARD
Definition: i2c.h:44
void gpio_output(gpio_t gpio, int value)
Definition: gpio.c:194
static int start_cpu(struct device *cpu)
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
u64 thunderx_get_core_clock(void)
Returns the core clock speed in Hz.
Definition: clock.c:57
u64 thunderx_get_ref_clock(void)
Returns the reference clock speed in Hz.
Definition: clock.c:37
u64 thunderx_get_io_clock(void)
Returns the I/O clock speed in Hz.
Definition: clock.c:45
size_t cpu_get_num_available_cores(void)
Return the number of cores available in the chip.
Definition: cpu.c:17
int gpio_strap_value(gpio_t gpio)
Definition: gpio.c:150
void soc_timer_init(void)
Definition: timer.c:119
#define NULL
Definition: stddef.h:19
void(* enable_dev)(struct device *dev)
Definition: device.h:24
void(* init)(struct device *dev)
Definition: device.h:42
Definition: device.h:107
struct device_operations * ops
Definition: device.h:143
int twsi_init(unsigned int bus, enum i2c_speed hz)
Definition: twsi.c:649
void udelay(uint32_t us)
Definition: udelay.c:15