xref: /aosp_15_r20/external/coreboot/src/soc/intel/braswell/bootblock/bootblock.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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