blob: 73ab03b64366983ec170b5fe743faa8db4eda216 [file] [log] [blame]
Angel Ponsae593872020-04-04 18:50:57 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Martin Roth5c354b92019-04-22 14:55:16 -06002
3#include <console/console.h>
4#include <device/mmio.h>
5#include <bootstate.h>
6#include <cpu/x86/smm.h>
Marshall Dawson39a4ac12019-06-20 16:28:33 -06007#include <cpu/x86/msr.h>
Martin Roth5c354b92019-04-22 14:55:16 -06008#include <device/device.h>
9#include <device/pci.h>
Martin Roth5c354b92019-04-22 14:55:16 -060010#include <device/pci_ops.h>
11#include <cbmem.h>
12#include <amdblocks/amd_pci_util.h>
Martin Roth5c354b92019-04-22 14:55:16 -060013#include <amdblocks/reset.h>
14#include <amdblocks/acpimmio.h>
15#include <amdblocks/lpc.h>
16#include <amdblocks/acpi.h>
Marshall Dawson39a4ac12019-06-20 16:28:33 -060017#include <soc/cpu.h>
Martin Roth5c354b92019-04-22 14:55:16 -060018#include <soc/southbridge.h>
Martin Roth5c354b92019-04-22 14:55:16 -060019#include <soc/smi.h>
20#include <soc/amd_pci_int_defs.h>
21#include <delay.h>
22#include <soc/pci_devs.h>
Martin Roth5c354b92019-04-22 14:55:16 -060023#include <soc/nvs.h>
24#include <types.h>
Furquan Shaikh69c28112020-04-28 18:57:52 -070025#include "chip.h"
Martin Roth5c354b92019-04-22 14:55:16 -060026
Marshall Dawson09d50672019-09-06 12:19:00 -060027#define FCH_AOAC_UART_FOR_CONSOLE \
28 (CONFIG_UART_FOR_CONSOLE == 0 ? FCH_AOAC_DEV_UART0 \
29 : CONFIG_UART_FOR_CONSOLE == 1 ? FCH_AOAC_DEV_UART1 \
Marshall Dawsonc0b8d0d2019-06-20 10:29:29 -060030 : CONFIG_UART_FOR_CONSOLE == 2 ? FCH_AOAC_DEV_UART2 \
31 : CONFIG_UART_FOR_CONSOLE == 3 ? FCH_AOAC_DEV_UART3 \
Marshall Dawson09d50672019-09-06 12:19:00 -060032 : -1)
33#if FCH_AOAC_UART_FOR_CONSOLE == -1
34# error Unsupported UART_FOR_CONSOLE chosen
35#endif
36
Martin Roth5c354b92019-04-22 14:55:16 -060037/*
38 * Table of devices that need their AOAC registers enabled and waited
39 * upon (usually about .55 milliseconds). Instead of individual delays
40 * waiting for each device to become available, a single delay will be
Marshall Dawson09d50672019-09-06 12:19:00 -060041 * executed. The console UART is handled separately from this table.
Martin Roth5c354b92019-04-22 14:55:16 -060042 */
Marshall Dawson09d50672019-09-06 12:19:00 -060043const static int aoac_devs[] = {
44 FCH_AOAC_DEV_AMBA,
45 FCH_AOAC_DEV_I2C2,
46 FCH_AOAC_DEV_I2C3,
47 FCH_AOAC_DEV_I2C4,
Marshall Dawson39a4ac12019-06-20 16:28:33 -060048 FCH_AOAC_DEV_ESPI,
Martin Roth5c354b92019-04-22 14:55:16 -060049};
50
Martin Roth5c354b92019-04-22 14:55:16 -060051/*
52 * Table of APIC register index and associated IRQ name. Using IDX_XXX_NAME
53 * provides a visible association with the index, therefore helping
54 * maintainability of table. If a new index/name is defined in
55 * amd_pci_int_defs.h, just add the pair at the end of this table.
56 * Order is not important.
57 */
58const static struct irq_idx_name irq_association[] = {
59 { PIRQ_A, "INTA#" },
60 { PIRQ_B, "INTB#" },
61 { PIRQ_C, "INTC#" },
62 { PIRQ_D, "INTD#" },
63 { PIRQ_E, "INTE#" },
Marshall Dawson39a4ac12019-06-20 16:28:33 -060064 { PIRQ_F, "INTF#/GENINT2" },
Martin Roth5c354b92019-04-22 14:55:16 -060065 { PIRQ_G, "INTG#" },
66 { PIRQ_H, "INTH#" },
67 { PIRQ_MISC, "Misc" },
68 { PIRQ_MISC0, "Misc0" },
69 { PIRQ_MISC1, "Misc1" },
70 { PIRQ_MISC2, "Misc2" },
71 { PIRQ_SIRQA, "Ser IRQ INTA" },
72 { PIRQ_SIRQB, "Ser IRQ INTB" },
73 { PIRQ_SIRQC, "Ser IRQ INTC" },
74 { PIRQ_SIRQD, "Ser IRQ INTD" },
75 { PIRQ_SCI, "SCI" },
76 { PIRQ_SMBUS, "SMBUS" },
77 { PIRQ_ASF, "ASF" },
Martin Roth5c354b92019-04-22 14:55:16 -060078 { PIRQ_PMON, "PerMon" },
79 { PIRQ_SD, "SD" },
Marshall Dawson39a4ac12019-06-20 16:28:33 -060080 { PIRQ_SDIO, "SDIO" },
81 { PIRQ_CIR, "CIR" },
82 { PIRQ_GPIOA, "GPIOa" },
83 { PIRQ_GPIOB, "GPIOb" },
84 { PIRQ_GPIOC, "GPIOc" },
Martin Roth5c354b92019-04-22 14:55:16 -060085 { PIRQ_SATA, "SATA" },
Marshall Dawson39a4ac12019-06-20 16:28:33 -060086 { PIRQ_EMMC, "eMMC" },
87 { PIRQ_GPP0, "GPP0" },
88 { PIRQ_GPP1, "GPP1" },
89 { PIRQ_GPP2, "GPP2" },
90 { PIRQ_GPP3, "GPP3" },
Martin Roth5c354b92019-04-22 14:55:16 -060091 { PIRQ_GPIO, "GPIO" },
92 { PIRQ_I2C0, "I2C0" },
93 { PIRQ_I2C1, "I2C1" },
94 { PIRQ_I2C2, "I2C2" },
95 { PIRQ_I2C3, "I2C3" },
96 { PIRQ_UART0, "UART0" },
97 { PIRQ_UART1, "UART1" },
Marshall Dawson39a4ac12019-06-20 16:28:33 -060098 { PIRQ_I2C4, "I2C4" },
99 { PIRQ_I2C5, "I2C5" },
100 { PIRQ_UART2, "UART2" },
101 { PIRQ_UART3, "UART3" },
Martin Roth5c354b92019-04-22 14:55:16 -0600102};
103
104const struct irq_idx_name *sb_get_apic_reg_association(size_t *size)
105{
106 *size = ARRAY_SIZE(irq_association);
107 return irq_association;
108}
109
Marshall Dawson09d50672019-09-06 12:19:00 -0600110static void power_on_aoac_device(int dev)
Martin Roth5c354b92019-04-22 14:55:16 -0600111{
112 uint8_t byte;
113
114 /* Power on the UART and AMBA devices */
Marshall Dawson09d50672019-09-06 12:19:00 -0600115 byte = aoac_read8(AOAC_DEV_D3_CTL(dev));
Martin Roth5c354b92019-04-22 14:55:16 -0600116 byte |= FCH_AOAC_PWR_ON_DEV;
Marshall Dawson09d50672019-09-06 12:19:00 -0600117 aoac_write8(AOAC_DEV_D3_CTL(dev), byte);
Martin Roth5c354b92019-04-22 14:55:16 -0600118}
119
Marshall Dawson09d50672019-09-06 12:19:00 -0600120static bool is_aoac_device_enabled(int dev)
Martin Roth5c354b92019-04-22 14:55:16 -0600121{
122 uint8_t byte;
123
Marshall Dawson09d50672019-09-06 12:19:00 -0600124 byte = aoac_read8(AOAC_DEV_D3_STATE(dev));
Martin Roth5c354b92019-04-22 14:55:16 -0600125 byte &= (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE);
126 if (byte == (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE))
127 return true;
128 else
129 return false;
130}
131
Marshall Dawson09d50672019-09-06 12:19:00 -0600132static void enable_aoac_console_uart(void)
133{
134 if (!CONFIG(PICASSO_UART))
135 return;
136
137 power_on_aoac_device(FCH_AOAC_UART_FOR_CONSOLE);
138}
139
140static bool is_aoac_console_uart_enabled(void)
141{
142 if (!CONFIG(PICASSO_UART))
143 return true;
144
145 return is_aoac_device_enabled(FCH_AOAC_UART_FOR_CONSOLE);
146}
147
Martin Roth5c354b92019-04-22 14:55:16 -0600148void enable_aoac_devices(void)
149{
150 bool status;
151 int i;
152
153 for (i = 0; i < ARRAY_SIZE(aoac_devs); i++)
Marshall Dawson09d50672019-09-06 12:19:00 -0600154 power_on_aoac_device(aoac_devs[i]);
155 enable_aoac_console_uart();
Martin Roth5c354b92019-04-22 14:55:16 -0600156
157 /* Wait for AOAC devices to indicate power and clock OK */
158 do {
159 udelay(100);
160 status = true;
161 for (i = 0; i < ARRAY_SIZE(aoac_devs); i++)
Marshall Dawson09d50672019-09-06 12:19:00 -0600162 status &= is_aoac_device_enabled(aoac_devs[i]);
163 status &= is_aoac_console_uart_enabled();
Martin Roth5c354b92019-04-22 14:55:16 -0600164 } while (!status);
165}
166
167static void sb_enable_lpc(void)
168{
169 u8 byte;
170
171 /* Enable LPC controller */
172 byte = pm_io_read8(PM_LPC_GATING);
173 byte |= PM_LPC_ENABLE;
174 pm_io_write8(PM_LPC_GATING, byte);
175}
176
Martin Roth5c354b92019-04-22 14:55:16 -0600177static void sb_enable_cf9_io(void)
178{
179 uint32_t reg = pm_read32(PM_DECODE_EN);
180
181 pm_write32(PM_DECODE_EN, reg | CF9_IO_EN);
182}
183
184static void sb_enable_legacy_io(void)
185{
186 uint32_t reg = pm_read32(PM_DECODE_EN);
187
188 pm_write32(PM_DECODE_EN, reg | LEGACY_IO_EN);
189}
190
Marshall Dawson0bd08062019-06-20 11:03:06 -0600191void sb_clk_output_48Mhz(void)
Martin Roth5c354b92019-04-22 14:55:16 -0600192{
193 u32 ctrl;
194
Martin Roth5c354b92019-04-22 14:55:16 -0600195 ctrl = misc_read32(MISC_CLK_CNTL1);
Marshall Dawson0bd08062019-06-20 11:03:06 -0600196 ctrl |= BP_X48M0_OUTPUT_EN;
Martin Roth5c354b92019-04-22 14:55:16 -0600197 misc_write32(MISC_CLK_CNTL1, ctrl);
198}
199
200static uintptr_t sb_init_spi_base(void)
201{
202 uintptr_t base;
203
204 /* Make sure the base address is predictable */
205 base = lpc_get_spibase();
206
207 if (base)
208 return base;
209
210 lpc_set_spibase(SPI_BASE_ADDRESS, SPI_ROM_ENABLE);
211 return SPI_BASE_ADDRESS;
212}
213
214void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm)
215{
216 uintptr_t base = sb_init_spi_base();
Furquan Shaikha0284db2020-04-28 18:45:20 -0700217
218 write16((void *)(base + SPI100_SPEED_CONFIG), SPI_SPEED_CFG(norm, fast, alt, tpm));
Martin Roth5c354b92019-04-22 14:55:16 -0600219 write16((void *)(base + SPI100_ENABLE), SPI_USE_SPI100);
220}
221
222void sb_disable_4dw_burst(void)
223{
224 uintptr_t base = sb_init_spi_base();
225 write16((void *)(base + SPI100_HOST_PREF_CONFIG),
226 read16((void *)(base + SPI100_HOST_PREF_CONFIG))
227 & ~SPI_RD4DW_EN_HOST);
228}
229
230void sb_read_mode(u32 mode)
231{
232 uintptr_t base = sb_init_spi_base();
Furquan Shaikha0284db2020-04-28 18:45:20 -0700233 uint32_t val = (read32((void *)(base + SPI_CNTRL0)) & ~SPI_READ_MODE_MASK);
234
235 write32((void *)(base + SPI_CNTRL0), val | SPI_READ_MODE(mode));
Martin Roth5c354b92019-04-22 14:55:16 -0600236}
237
Furquan Shaikh0eabe132020-04-28 21:57:07 -0700238static void sb_spi_config_mb_modes(void)
Furquan Shaikh173c7c42020-04-28 18:55:59 -0700239{
Furquan Shaikh69c28112020-04-28 18:57:52 -0700240 const struct soc_amd_picasso_config *cfg = config_of_soc();
241
242 sb_read_mode(cfg->spi_read_mode);
243 sb_set_spi100(cfg->spi_normal_speed, cfg->spi_fast_speed, cfg->spi_altio_speed,
244 cfg->spi_tpm_speed);
Furquan Shaikh173c7c42020-04-28 18:55:59 -0700245}
246
Furquan Shaikh0eabe132020-04-28 21:57:07 -0700247static void sb_spi_config_em100_modes(void)
248{
249 sb_read_mode(SPI_READ_MODE_NORMAL33M);
250 sb_set_spi100(SPI_SPEED_16M, SPI_SPEED_16M, SPI_SPEED_16M, SPI_SPEED_16M);
251}
252
253static void sb_spi_config_modes(void)
254{
255 if (CONFIG(EM100))
256 sb_spi_config_em100_modes();
257 else
258 sb_spi_config_mb_modes();
259}
260
Furquan Shaikh173c7c42020-04-28 18:55:59 -0700261static void sb_spi_init(void)
262{
263 lpc_enable_spi_prefetch();
264 sb_init_spi_base();
265 sb_disable_4dw_burst();
266 sb_spi_config_modes();
267}
268
Martin Roth5c354b92019-04-22 14:55:16 -0600269static void fch_smbus_init(void)
270{
Aaron Durbin3bee7df2020-01-28 10:58:13 -0700271 /* 400 kHz smbus speed. */
272 const uint8_t smbus_speed = (66000000 / (400000 * 4));
273
Martin Roth5c354b92019-04-22 14:55:16 -0600274 pm_write8(SMB_ASF_IO_BASE, SMB_BASE_ADDR >> 8);
Aaron Durbin3bee7df2020-01-28 10:58:13 -0700275 smbus_write8(SMBTIMING, smbus_speed);
Martin Roth5c354b92019-04-22 14:55:16 -0600276 /* Clear all SMBUS status bits */
277 smbus_write8(SMBHSTSTAT, SMBHST_STAT_CLEAR);
278 smbus_write8(SMBSLVSTAT, SMBSLV_STAT_CLEAR);
279 asf_write8(SMBHSTSTAT, SMBHST_STAT_CLEAR);
280 asf_write8(SMBSLVSTAT, SMBSLV_STAT_CLEAR);
281}
282
283/* Before console init */
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600284void fch_pre_init(void)
Martin Roth5c354b92019-04-22 14:55:16 -0600285{
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600286 /* Turn on LPC in case the PSP didn't use it. However, ensure all
287 * decoding is cleared as the PSP may have enabled decode paths. */
Martin Roth5c354b92019-04-22 14:55:16 -0600288 sb_enable_lpc();
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600289 lpc_disable_decodes();
290
291 if (CONFIG(POST_IO) && (CONFIG_POST_IO_PORT == 0x80)
292 && CONFIG(PICASSO_LPC_IOMUX))
293 lpc_enable_port80();
Furquan Shaikh173c7c42020-04-28 18:55:59 -0700294 sb_spi_init();
Michał Żygowski73a544d2019-11-24 14:16:34 +0100295 enable_acpimmio_decode_pm04();
Martin Roth5c354b92019-04-22 14:55:16 -0600296 fch_smbus_init();
297 sb_enable_cf9_io();
Martin Roth5c354b92019-04-22 14:55:16 -0600298 sb_enable_legacy_io();
299 enable_aoac_devices();
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600300 sb_reset_i2c_slaves();
Marshall Dawsonc0b8d0d2019-06-20 10:29:29 -0600301 if (CONFIG(PICASSO_UART))
302 set_uart_config(CONFIG_UART_FOR_CONSOLE);
Martin Roth5c354b92019-04-22 14:55:16 -0600303}
304
305static void print_num_status_bits(int num_bits, uint32_t status,
306 const char *const bit_names[])
307{
308 int i;
309
310 if (!status)
311 return;
312
313 for (i = num_bits - 1; i >= 0; i--) {
314 if (status & (1 << i)) {
315 if (bit_names[i])
316 printk(BIOS_DEBUG, "%s ", bit_names[i]);
317 else
318 printk(BIOS_DEBUG, "BIT%d ", i);
319 }
320 }
321}
322
323static void sb_print_pmxc0_status(void)
324{
325 /* PMxC0 S5/Reset Status shows the source of previous reset. */
326 uint32_t pmxc0_status = pm_read32(PM_RST_STATUS);
327
328 static const char *const pmxc0_status_bits[32] = {
329 [0] = "ThermalTrip",
330 [1] = "FourSecondPwrBtn",
331 [2] = "Shutdown",
332 [3] = "ThermalTripFromTemp",
333 [4] = "RemotePowerDownFromASF",
334 [5] = "ShutDownFan0",
335 [16] = "UserRst",
336 [17] = "SoftPciRst",
337 [18] = "DoInit",
338 [19] = "DoReset",
339 [20] = "DoFullReset",
340 [21] = "SleepReset",
341 [22] = "KbReset",
342 [23] = "LtReset",
343 [24] = "FailBootRst",
344 [25] = "WatchdogIssueReset",
345 [26] = "RemoteResetFromASF",
346 [27] = "SyncFlood",
347 [28] = "HangReset",
348 [29] = "EcWatchdogRst",
349 };
350
351 printk(BIOS_DEBUG, "PMxC0 STATUS: 0x%x ", pmxc0_status);
352 print_num_status_bits(ARRAY_SIZE(pmxc0_status_bits), pmxc0_status,
353 pmxc0_status_bits);
354 printk(BIOS_DEBUG, "\n");
355}
356
357/* After console init */
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600358void fch_early_init(void)
Martin Roth5c354b92019-04-22 14:55:16 -0600359{
360 sb_print_pmxc0_status();
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600361 i2c_soc_early_init();
Aaron Durbin1d0b99b2020-04-11 11:58:57 -0600362
363 if (CONFIG(DISABLE_SPI_FLASH_ROM_SHARING))
364 lpc_disable_spi_rom_sharing();
Martin Roth5c354b92019-04-22 14:55:16 -0600365}
366
367void sb_enable(struct device *dev)
368{
369 printk(BIOS_DEBUG, "%s\n", __func__);
370}
371
372static void sb_init_acpi_ports(void)
373{
374 u32 reg;
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600375 msr_t cst_addr;
Martin Roth5c354b92019-04-22 14:55:16 -0600376
377 /* We use some of these ports in SMM regardless of whether or not
378 * ACPI tables are generated. Enable these ports indiscriminately.
379 */
380
381 pm_write16(PM_EVT_BLK, ACPI_PM_EVT_BLK);
382 pm_write16(PM1_CNT_BLK, ACPI_PM1_CNT_BLK);
383 pm_write16(PM_TMR_BLK, ACPI_PM_TMR_BLK);
384 pm_write16(PM_GPE0_BLK, ACPI_GPE0_BLK);
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600385
Michał Żygowski9550e972020-03-20 13:56:46 +0100386 /* CpuControl is in \_SB.CP00, 6 bytes */
Marshall Dawson39a4ac12019-06-20 16:28:33 -0600387 cst_addr.hi = 0;
388 cst_addr.lo = ACPI_CPU_CONTROL;
389 wrmsr(CSTATE_BASE_REG, cst_addr);
Martin Roth5c354b92019-04-22 14:55:16 -0600390
391 if (CONFIG(HAVE_SMI_HANDLER)) {
392 /* APMC - SMI Command Port */
393 pm_write16(PM_ACPI_SMI_CMD, APM_CNT);
394 configure_smi(SMITYPE_SMI_CMD_PORT, SMI_MODE_SMI);
395
396 /* SMI on SlpTyp requires sending SMI before completion
397 * response of the I/O write. The BKDG also specifies
398 * clearing ForceStpClkRetry for SMI trapping.
399 */
400 reg = pm_read32(PM_PCI_CTRL);
401 reg |= FORCE_SLPSTATE_RETRY;
Martin Roth5c354b92019-04-22 14:55:16 -0600402 pm_write32(PM_PCI_CTRL, reg);
403
404 /* Disable SlpTyp feature */
405 reg = pm_read8(PM_RST_CTRL1);
406 reg &= ~SLPTYPE_CONTROL_EN;
407 pm_write8(PM_RST_CTRL1, reg);
408
409 configure_smi(SMITYPE_SLP_TYP, SMI_MODE_SMI);
410 } else {
411 pm_write16(PM_ACPI_SMI_CMD, 0);
412 }
413
414 /* Decode ACPI registers and enable standard features */
415 pm_write8(PM_ACPI_CONF, PM_ACPI_DECODE_STD |
416 PM_ACPI_GLOBAL_EN |
417 PM_ACPI_RTC_EN_EN |
418 PM_ACPI_TIMER_EN_EN);
419}
420
421static int get_index_bit(uint32_t value, uint16_t limit)
422{
423 uint16_t i;
424 uint32_t t;
425
426 if (limit >= TOTAL_BITS(uint32_t))
427 return -1;
428
429 /* get a mask of valid bits. Ex limit = 3, set bits 0-2 */
430 t = (1 << limit) - 1;
431 if ((value & t) == 0)
432 return -1;
433 t = 1;
434 for (i = 0; i < limit; i++) {
435 if (value & t)
436 break;
437 t <<= 1;
438 }
439 return i;
440}
441
442static void set_nvs_sws(void *unused)
443{
444 struct soc_power_reg *sws;
445 struct global_nvs_t *gnvs;
446 int index;
447
448 sws = cbmem_find(CBMEM_ID_POWER_STATE);
449 if (sws == NULL)
450 return;
451 gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
452 if (gnvs == NULL)
453 return;
454
455 index = get_index_bit(sws->pm1_sts & sws->pm1_en, PM1_LIMIT);
456 if (index < 0)
457 gnvs->pm1i = ~0ULL;
458 else
459 gnvs->pm1i = index;
460
461 index = get_index_bit(sws->gpe0_sts & sws->gpe0_en, GPE0_LIMIT);
462 if (index < 0)
463 gnvs->gpei = ~0ULL;
464 else
465 gnvs->gpei = index;
466}
467
468BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, set_nvs_sws, NULL);
469
470void southbridge_init(void *chip_info)
471{
Aaron Durbin09f60ff2020-04-09 15:24:50 -0600472 i2c_soc_init();
Martin Roth5c354b92019-04-22 14:55:16 -0600473 sb_init_acpi_ports();
474 acpi_clear_pm1_status();
475}
476
477static void set_sb_final_nvs(void)
478{
Martin Roth5c354b92019-04-22 14:55:16 -0600479 struct global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
480 if (gnvs == NULL)
481 return;
482
Marshall Dawson09d50672019-09-06 12:19:00 -0600483 gnvs->aoac.ic2e = is_aoac_device_enabled(FCH_AOAC_DEV_I2C2);
484 gnvs->aoac.ic3e = is_aoac_device_enabled(FCH_AOAC_DEV_I2C3);
485 gnvs->aoac.ic4e = is_aoac_device_enabled(FCH_AOAC_DEV_I2C4);
486 gnvs->aoac.ut0e = is_aoac_device_enabled(FCH_AOAC_DEV_UART0);
487 gnvs->aoac.ut1e = is_aoac_device_enabled(FCH_AOAC_DEV_UART1);
Marshall Dawsonc0b8d0d2019-06-20 10:29:29 -0600488 gnvs->aoac.ut2e = is_aoac_device_enabled(FCH_AOAC_DEV_UART2);
489 gnvs->aoac.ut3e = is_aoac_device_enabled(FCH_AOAC_DEV_UART3);
Martin Roth5c354b92019-04-22 14:55:16 -0600490 gnvs->aoac.espi = 1;
Martin Roth5c354b92019-04-22 14:55:16 -0600491}
492
493void southbridge_final(void *chip_info)
494{
495 uint8_t restored_power = PM_S5_AT_POWER_RECOVERY;
496
497 if (CONFIG(MAINBOARD_POWER_RESTORE))
498 restored_power = PM_RESTORE_S0_IF_PREV_S0;
499 pm_write8(PM_RTC_SHADOW, restored_power);
500
501 set_sb_final_nvs();
502}
503
504/*
505 * Update the PCI devices with a valid IRQ number
506 * that is set in the mainboard PCI_IRQ structures.
507 */
508static void set_pci_irqs(void *unused)
509{
510 /* Write PCI_INTR regs 0xC00/0xC01 */
511 write_pci_int_table();
512
513 /* Write IRQs for all devicetree enabled devices */
514 write_pci_cfg_irqs();
515}
516
517/*
518 * Hook this function into the PCI state machine
519 * on entry into BS_DEV_ENABLE.
520 */
521BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, set_pci_irqs, NULL);