libpayload: configs: Add new config.featuretest to broaden CI
[coreboot.git] / src / soc / intel / broadwell / pch / bootblock.c
blob80c77212cf4061f17f49a74006b66922ad7454ed
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/bootblock.h>
4 #include <arch/hpet.h>
5 #include <device/pci_ops.h>
6 #include <soc/iomap.h>
7 #include <soc/lpc.h>
8 #include <soc/pci_devs.h>
9 #include <soc/rcba.h>
10 #include <soc/spi.h>
11 #include <soc/pm.h>
12 #include <soc/romstage.h>
13 #include <southbridge/intel/common/early_spi.h>
15 static void map_rcba(void)
17 pci_write_config32(PCH_DEV_LPC, RCBA, CONFIG_FIXED_RCBA_MMIO_BASE | 1);
20 static void enable_port80_on_lpc(void)
22 /* Enable port 80 POST on LPC. The chipset does this by default,
23 * but it doesn't appear to hurt anything. */
24 u32 gcs = RCBA32(GCS);
25 gcs = gcs & ~0x4;
26 RCBA32(GCS) = gcs;
29 static void set_spi_speed(void)
31 u32 fdod;
32 u8 ssfc;
34 /* Observe SPI Descriptor Component Section 0 */
35 SPIBAR32(SPIBAR_FDOC) = 0x1000;
37 /* Extract the Write/Erase SPI Frequency from descriptor */
38 fdod = SPIBAR32(SPIBAR_FDOD);
39 fdod >>= 24;
40 fdod &= 7;
42 /* Set Software Sequence frequency to match */
43 ssfc = SPIBAR8(SPIBAR_SSFC + 2);
44 ssfc &= ~7;
45 ssfc |= fdod;
46 SPIBAR8(SPIBAR_SSFC + 2) = ssfc;
49 static void pch_enable_bars(void)
51 /* Set up southbridge BARs */
52 pci_write_config32(PCH_DEV_LPC, RCBA, CONFIG_FIXED_RCBA_MMIO_BASE | 1);
54 pci_write_config32(PCH_DEV_LPC, PMBASE, ACPI_BASE_ADDRESS | 1);
56 pci_write_config8(PCH_DEV_LPC, ACPI_CNTL, ACPI_EN);
58 pci_write_config32(PCH_DEV_LPC, GPIO_BASE, GPIO_BASE_ADDRESS | 1);
60 /* Enable GPIO functionality. */
61 pci_write_config8(PCH_DEV_LPC, GPIO_CNTL, GPIO_EN);
64 static void pch_early_lpc(void)
66 pch_enable_bars();
68 /* Set COM1/COM2 decode range */
69 pci_write_config16(PCH_DEV_LPC, LPC_IO_DEC, 0x0010);
71 /* Enable SuperIO + MC + COM1 + PS/2 Keyboard/Mouse */
72 u16 lpc_config = CNF1_LPC_EN | CNF2_LPC_EN | GAMEL_LPC_EN |
73 COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN;
74 pci_write_config16(PCH_DEV_LPC, LPC_EN, lpc_config);
76 /* Enable IOAPIC */
77 RCBA16(OIC) = 0x0100;
79 /* Read back for posted write */
80 (void)RCBA16(OIC);
82 /* Set HPET address and enable it */
83 RCBA32_AND_OR(HPTC, ~3, 1 << 7);
86 * Reading the register back guarantees that the write is
87 * done before we use the configured base address below.
89 (void)RCBA32(HPTC);
91 /* Enable HPET to start counter */
92 setbits32((void *)HPET_BASE_ADDRESS + 0x10, 1 << 0);
94 /* Disable reset */
95 RCBA32_OR(GCS, 1 << 5);
97 /* TCO timer halt */
98 u16 reg16 = inb(ACPI_BASE_ADDRESS + TCO1_CNT);
99 reg16 |= TCO_TMR_HLT;
100 outb(reg16, ACPI_BASE_ADDRESS + TCO1_CNT);
102 /* Enable upper 128 bytes of CMOS */
103 RCBA32_OR(RC, 1 << 2);
105 /* Disable unused device (always) */
106 RCBA32_OR(FD, PCH_DISABLE_ALWAYS);
109 /* Defined in Lynx Point code */
110 void uart_bootblock_init(void);
112 void bootblock_early_southbridge_init(void)
114 map_rcba();
115 enable_spi_prefetching_and_caching();
116 enable_port80_on_lpc();
117 set_spi_speed();
118 pch_early_lpc();
120 if (CONFIG(SERIALIO_UART_CONSOLE))
121 uart_bootblock_init();