mb/google/nissa/var/rull: Configure Acoustic noise mitigation
[coreboot2.git] / src / soc / amd / common / block / lpc / lpc_util.c
blob309825a8410b07e92e4fa72938985134fa55f451
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <assert.h>
4 #include <stdint.h>
5 #include <device/device.h>
6 #include <device/pci_ops.h>
7 #include <device/pci_def.h>
8 #include <amdblocks/acpimmio.h>
9 #include <amdblocks/lpc.h>
10 #include <soc/iomap.h>
11 #include <soc/lpc.h>
12 #include <soc/southbridge.h>
14 /* The LPC-ISA bridge is always at D14F3 */
15 #if !defined(__SIMPLE_DEVICE__)
16 #define _LPCB_DEV pcidev_on_root(0x14, 0x3)
17 #else
18 #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3)
19 #endif
22 * Structure to simplify code obtaining the total of used wide IO
23 * registers and the size assigned to each.
25 static const struct wide_io_ioport_and_bits {
26 uint32_t enable;
27 uint16_t port;
28 uint8_t alt;
29 } wio_io_en[] = {
31 .enable = LPC_WIDEIO0_ENABLE,
32 .port = LPC_WIDEIO_GENERIC_PORT,
33 .alt = LPC_ALT_WIDEIO0_ENABLE
36 .enable = LPC_WIDEIO1_ENABLE,
37 .port = LPC_WIDEIO1_GENERIC_PORT,
38 .alt = LPC_ALT_WIDEIO1_ENABLE
41 .enable = LPC_WIDEIO2_ENABLE,
42 .port = LPC_WIDEIO2_GENERIC_PORT,
43 .alt = LPC_ALT_WIDEIO2_ENABLE
47 /**
48 * @brief Find the size of a particular wide IO
50 * @param index = index of desired wide IO
52 * @return size of desired wide IO
54 uint16_t lpc_wideio_size(int index)
56 uint32_t enable_register;
57 uint16_t size = 0;
58 uint8_t alternate_register;
60 if (index >= ARRAY_SIZE(wio_io_en))
61 return size;
62 enable_register = pci_read_config32(_LPCB_DEV,
63 LPC_IO_OR_MEM_DECODE_ENABLE);
64 alternate_register = pci_read_config8(_LPCB_DEV,
65 LPC_ALT_WIDEIO_RANGE_ENABLE);
66 if (enable_register & wio_io_en[index].enable)
67 size = (alternate_register & wio_io_en[index].alt) ?
68 16 : 512;
69 return size;
72 /**
73 * @brief Identify if any LPC wide IO is covering the IO range
75 * @param start = start of IO range
76 * @param size = size of IO range
78 * @return Index of wide IO covering the range or error
80 int lpc_find_wideio_range(uint16_t start, uint16_t size)
82 int i, index = WIDEIO_RANGE_ERROR;
83 uint16_t end, current_size, start_wideio, end_wideio;
85 end = start + size;
86 for (i = 0; i < ARRAY_SIZE(wio_io_en); i++) {
87 current_size = lpc_wideio_size(i);
88 if (current_size == 0)
89 continue;
90 start_wideio = pci_read_config16(_LPCB_DEV,
91 wio_io_en[i].port);
92 end_wideio = start_wideio + current_size;
93 if ((start >= start_wideio) && (end <= end_wideio)) {
94 index = i;
95 break;
98 return index;
102 * @brief Program a LPC wide IO to support an IO range
104 * @param start = start of range to be routed through wide IO
105 * @param size = size of range to be routed through wide IO
107 * @return Index of wide IO register used or error
109 int lpc_set_wideio_range(uint16_t start, uint16_t size)
111 int i, index = WIDEIO_RANGE_ERROR;
112 uint32_t enable_register;
113 uint8_t alternate_register;
115 enable_register = pci_read_config32(_LPCB_DEV,
116 LPC_IO_OR_MEM_DECODE_ENABLE);
117 alternate_register = pci_read_config8(_LPCB_DEV,
118 LPC_ALT_WIDEIO_RANGE_ENABLE);
119 for (i = 0; i < ARRAY_SIZE(wio_io_en); i++) {
120 if (enable_register & wio_io_en[i].enable)
121 continue;
122 index = i;
123 pci_write_config16(_LPCB_DEV, wio_io_en[i].port, start);
124 enable_register |= wio_io_en[i].enable;
125 pci_write_config32(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE,
126 enable_register);
127 if (size <= 16)
128 alternate_register |= wio_io_en[i].alt;
129 else
130 alternate_register &= ~wio_io_en[i].alt;
131 pci_write_config8(_LPCB_DEV,
132 LPC_ALT_WIDEIO_RANGE_ENABLE,
133 alternate_register);
134 break;
136 return index;
139 void lpc_enable_port80(void)
141 uint32_t tmp;
143 tmp = pci_read_config32(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE);
144 tmp |= DECODE_IO_PORT_ENABLE4;
145 pci_write_config32(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, tmp);
148 void lpc_enable_sio_decode(const bool addr)
150 uint32_t decodes;
151 uint32_t enable;
153 decodes = pci_read_config32(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE);
154 enable = addr == LPC_SELECT_SIO_2E2F ?
155 DECODE_SIO_ENABLE : DECODE_ALTERNATE_SIO_ENABLE;
156 decodes |= enable;
157 pci_write_config32(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, decodes);
160 void lpc_enable_decode(uint32_t decodes)
162 pci_write_config32(_LPCB_DEV, LPC_IO_PORT_DECODE_ENABLE, decodes);
166 * Clear all decoding to the LPC bus and erase any range registers associated
167 * with the enable bits.
169 void lpc_disable_decodes(void)
171 uint32_t reg;
173 lpc_enable_decode(0);
174 reg = pci_read_config32(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE);
175 reg &= LPC_SYNC_TIMEOUT_COUNT_MASK | LPC_SYNC_TIMEOUT_COUNT_ENABLE;
176 pci_write_config32(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, reg);
177 pci_write_config32(_LPCB_DEV, LPC_IO_PORT_DECODE_ENABLE, 0);
179 /* D14F3x48 enables ranges configured in additional registers */
180 pci_write_config32(_LPCB_DEV, LPC_MEM_PORT1, 0);
181 pci_write_config32(_LPCB_DEV, LPC_MEM_PORT0, 0);
182 pci_write_config32(_LPCB_DEV, LPC_WIDEIO2_GENERIC_PORT, 0);
185 uintptr_t lpc_spibase(void)
187 u32 base, enables;
189 /* Make sure the base address is predictable */
190 base = pci_read_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER);
191 enables = base & SPI_PRESERVE_BITS;
192 base &= ~(SPI_PRESERVE_BITS | SPI_BASE_RESERVED);
194 if (!base) {
195 base = SPI_BASE_ADDRESS;
196 pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER,
197 base | enables | SPI_ROM_ENABLE);
198 /* PCI_COMMAND_MEMORY is read-only and enabled. */
200 return base;
204 * Enable FCH to decode TPM associated Memory and IO regions
206 * Enable decoding of TPM cycles defined in TPM 1.2 spec
207 * Enable decoding of legacy TPM addresses: IO addresses 0x7f-
208 * 0x7e and 0xef-0xee.
209 * This function should be called if TPM is connected in any way to the FCH and
210 * conforms to the regions decoded.
211 * Absent any other routing configuration the TPM cycles will be claimed by the
212 * LPC bus
214 void lpc_tpm_decode(void)
216 u32 value;
218 value = pci_read_config32(_LPCB_DEV, LPC_TRUSTED_PLATFORM_MODULE);
219 value |= TPM_12_EN | TPM_LEGACY_EN;
220 pci_write_config32(_LPCB_DEV, LPC_TRUSTED_PLATFORM_MODULE, value);
224 * Enable FCH to decode TPM associated Memory and IO regions to SPI
226 * This should be used if TPM is connected to SPI bus.
227 * Assumes SPI address space is already configured via a call to lpc_spibase().
229 void lpc_tpm_decode_spi(void)
231 /* Enable TPM decoding to FCH */
232 lpc_tpm_decode();
234 /* Route TPM accesses to SPI */
235 u32 spibase = pci_read_config32(_LPCB_DEV,
236 SPI_BASE_ADDRESS_REGISTER);
237 pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER, spibase
238 | ROUTE_TPM_2_SPI);
242 * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
244 * Hardware should enable LPC ROM by pin straps. This function does not
245 * handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
247 * The southbridge power-on default is to map 512K ROM space.
250 void lpc_enable_rom(void)
252 u8 reg8;
255 * Decode variable LPC ROM address ranges 1 and 2.
256 * Bits 3-4 are not defined in any publicly available datasheet
258 reg8 = pci_read_config8(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE);
259 reg8 |= (1 << 3) | (1 << 4);
260 pci_write_config8(_LPCB_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, reg8);
263 * LPC ROM address range 1:
264 * Enable LPC ROM range mirroring start at 0x000e(0000).
266 pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE1_START, 0x000e);
268 /* Enable LPC ROM range mirroring end at 0x000f(ffff). */
269 pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE1_END, 0x000f);
272 * LPC ROM address range 2:
274 * Enable LPC ROM range start at:
275 * 0xfff8(0000): 512KB
276 * 0xfff0(0000): 1MB
277 * 0xffe0(0000): 2MB
278 * 0xffc0(0000): 4MB
280 pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE2_START, 0x10000
281 - (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
283 /* Enable LPC ROM range end at 0xffff(ffff). */
284 pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE2_END, 0xffff);
287 void lpc_enable_spi_prefetch(void)
289 uint32_t dword;
291 dword = pci_read_config32(_LPCB_DEV, LPC_ROM_DMA_EC_HOST_CONTROL);
292 dword |= SPI_FROM_HOST_PREFETCH_EN | SPI_FROM_USB_PREFETCH_EN;
293 pci_write_config32(_LPCB_DEV, LPC_ROM_DMA_EC_HOST_CONTROL, dword);
296 void lpc_disable_spi_rom_sharing(void)
298 u8 byte;
300 if (!CONFIG(PROVIDES_ROM_SHARING))
301 dead_code();
303 byte = pci_read_config8(_LPCB_DEV, LPC_PCI_CONTROL);
304 byte &= ~VW_ROM_SHARING_EN;
305 byte &= ~EXT_ROM_SHARING_EN;
306 pci_write_config8(_LPCB_DEV, LPC_PCI_CONTROL, byte);
309 uintptr_t lpc_get_spibase(void)
311 u32 base;
313 base = pci_read_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER);
314 base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT);
315 return (uintptr_t)base;
318 void lpc_set_spibase(uint32_t base)
320 uint32_t reg32;
322 reg32 = pci_read_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER);
324 reg32 &= SPI_BASE_ALIGNMENT - 1; /* preserve only reserved, enables */
325 reg32 |= ALIGN_DOWN(base, SPI_BASE_ALIGNMENT);
327 pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER, reg32);
330 void lpc_enable_spi_rom(uint32_t enable)
332 uint32_t reg32;
334 /* only two types of CS# enables are allowed */
335 enable &= SPI_ROM_ENABLE | SPI_ROM_ALT_ENABLE;
337 reg32 = pci_read_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER);
339 reg32 &= ~(SPI_ROM_ENABLE | SPI_ROM_ALT_ENABLE);
340 reg32 |= enable;
342 pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER, reg32);
345 static void lpc_enable_controller(void)
347 u8 byte;
349 /* Enable LPC controller */
350 byte = pm_read8(PM_LPC_GATING);
351 byte |= PM_LPC_ENABLE;
352 pm_write8(PM_LPC_GATING, byte);
355 void lpc_early_init(void)
357 lpc_enable_controller();
358 lpc_disable_decodes();
359 lpc_set_spibase(SPI_BASE_ADDRESS);