1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <arch/io.h>
4 #include <bootblock_common.h>
5 #include <console/console.h>
6 #include <device/pci_ops.h>
7 #include <fsp/util.h>
8 #include <gpio.h>
9 #include <pc80/mc146818rtc.h>
10 #include <soc/iomap.h>
11 #include <soc/iosf.h>
12 #include <soc/lpc.h>
13 #include <soc/msr.h>
14 #include <soc/pm.h>
15 #include <soc/spi.h>
16 #include <version.h>
17
bootblock_c_entry(uint64_t base_timestamp)18 asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
19 {
20 /* Call lib/bootblock.c main */
21 bootblock_main_with_basetime(base_timestamp);
22 }
23
program_base_addresses(void)24 static void program_base_addresses(void)
25 {
26 uint32_t reg;
27 const uint32_t lpc_dev = PCI_DEV(0, LPC_DEV, LPC_FUNC);
28
29 /* Memory Mapped IO registers. */
30 reg = PMC_BASE_ADDRESS | 2;
31 pci_write_config32(lpc_dev, PBASE, reg);
32 reg = IO_BASE_ADDRESS | 2;
33 pci_write_config32(lpc_dev, IOBASE, reg);
34 reg = ILB_BASE_ADDRESS | 2;
35 pci_write_config32(lpc_dev, IBASE, reg);
36 reg = SPI_BASE_ADDRESS | 2;
37 pci_write_config32(lpc_dev, SBASE, reg);
38 reg = MPHY_BASE_ADDRESS | 2;
39 pci_write_config32(lpc_dev, MPBASE, reg);
40 reg = PUNIT_BASE_ADDRESS | 2;
41 pci_write_config32(lpc_dev, PUBASE, reg);
42 reg = RCBA_BASE_ADDRESS | 1;
43 pci_write_config32(lpc_dev, RCBA, reg);
44
45 /* IO Port Registers. */
46 reg = ACPI_BASE_ADDRESS | 2;
47 pci_write_config32(lpc_dev, ABASE, reg);
48 reg = GPIO_BASE_ADDRESS | 2;
49 pci_write_config32(lpc_dev, GBASE, reg);
50 }
51
tco_disable(void)52 static void tco_disable(void)
53 {
54 uint32_t reg;
55
56 reg = inl(ACPI_BASE_ADDRESS + TCO1_CNT);
57 reg |= TCO_TMR_HALT;
58 outl(reg, ACPI_BASE_ADDRESS + TCO1_CNT);
59 }
60
spi_init(void)61 static void spi_init(void)
62 {
63 void *scs = (void *)(SPI_BASE_ADDRESS + SCS);
64 void *bcr = (void *)(SPI_BASE_ADDRESS + BCR);
65 uint32_t reg;
66
67 /* Disable generating SMI when setting WPD bit. */
68 write32(scs, read32(scs) & ~SMIWPEN);
69 /*
70 * Enable caching and prefetching in the SPI controller. Disable
71 * the SMM-only BIOS write and set WPD bit.
72 */
73 reg = (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH | BCR_WPD;
74 reg &= ~EISS;
75 write32(bcr, reg);
76 }
77
soc_rtc_init(void)78 static void soc_rtc_init(void)
79 {
80 int rtc_failed = rtc_failure();
81
82 if (rtc_failed)
83 printk(BIOS_ERR, "RTC Failure detected. Resetting date to %x/%x/%x%x\n",
84 coreboot_build_date.month, coreboot_build_date.day,
85 coreboot_build_date.century, coreboot_build_date.year);
86
87 cmos_init(rtc_failed);
88 }
89
setup_mmconfig(void)90 static void setup_mmconfig(void)
91 {
92 uint32_t reg;
93
94 /*
95 * Set up the MMCONF range. The register lives in the BUNIT. The IO variant of the
96 * config access needs to be used initially to properly configure as the IOSF access
97 * registers live in PCI config space.
98 */
99 reg = 0;
100 /* Clear the extended register. */
101 pci_io_write_config32(IOSF_PCI_DEV, MCRX_REG, reg);
102 reg = CONFIG_ECAM_MMCONF_BASE_ADDRESS | 1;
103 pci_io_write_config32(IOSF_PCI_DEV, MDR_REG, reg);
104 reg = IOSF_OPCODE(IOSF_OP_WRITE_BUNIT) | IOSF_PORT(IOSF_PORT_BUNIT) |
105 IOSF_REG(BUNIT_MMCONF_REG) | IOSF_BYTE_EN;
106 pci_io_write_config32(IOSF_PCI_DEV, MCR_REG, reg);
107 }
108
bootblock_soc_early_init(void)109 void bootblock_soc_early_init(void)
110 {
111 /* Allow memory-mapped PCI config access */
112 setup_mmconfig();
113
114 /* Early chipset initialization */
115 program_base_addresses();
116 tco_disable();
117 }
bootblock_soc_init(void)118 void bootblock_soc_init(void)
119 {
120 report_fsp_output();
121
122 /* Continue chipset initialization */
123 soc_rtc_init();
124 set_max_freq();
125 spi_init();
126
127 lpc_init();
128 }
129