xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/block/lpc/lpc_util.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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>
13 
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
20 
21 /*
22  * Structure to simplify code obtaining the total of used wide IO
23  * registers and the size assigned to each.
24  */
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[] = {
30 	{
31 		.enable = LPC_WIDEIO0_ENABLE,
32 		.port = LPC_WIDEIO_GENERIC_PORT,
33 		.alt = LPC_ALT_WIDEIO0_ENABLE
34 	},
35 	{
36 		.enable = LPC_WIDEIO1_ENABLE,
37 		.port = LPC_WIDEIO1_GENERIC_PORT,
38 		.alt = LPC_ALT_WIDEIO1_ENABLE
39 	},
40 	{
41 		.enable = LPC_WIDEIO2_ENABLE,
42 		.port = LPC_WIDEIO2_GENERIC_PORT,
43 		.alt = LPC_ALT_WIDEIO2_ENABLE
44 	}
45 };
46 
47 /**
48  * @brief Find the size of a particular wide IO
49  *
50  * @param index = index of desired wide IO
51  *
52  * @return size of desired wide IO
53  */
lpc_wideio_size(int index)54 uint16_t lpc_wideio_size(int index)
55 {
56 	uint32_t enable_register;
57 	uint16_t size = 0;
58 	uint8_t alternate_register;
59 
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;
70 }
71 
72 /**
73  * @brief Identify if any LPC wide IO is covering the IO range
74  *
75  * @param start = start of IO range
76  * @param size = size of IO range
77  *
78  * @return Index of wide IO covering the range or error
79  */
lpc_find_wideio_range(uint16_t start,uint16_t size)80 int lpc_find_wideio_range(uint16_t start, uint16_t size)
81 {
82 	int i, index = WIDEIO_RANGE_ERROR;
83 	uint16_t end, current_size, start_wideio, end_wideio;
84 
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;
96 		}
97 	}
98 	return index;
99 }
100 
101 /**
102  * @brief Program a LPC wide IO to support an IO range
103  *
104  * @param start = start of range to be routed through wide IO
105  * @param size = size of range to be routed through wide IO
106  *
107  * @return Index of wide IO register used or error
108  */
lpc_set_wideio_range(uint16_t start,uint16_t size)109 int lpc_set_wideio_range(uint16_t start, uint16_t size)
110 {
111 	int i, index = WIDEIO_RANGE_ERROR;
112 	uint32_t enable_register;
113 	uint8_t alternate_register;
114 
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;
135 	}
136 	return index;
137 }
138 
lpc_enable_port80(void)139 void lpc_enable_port80(void)
140 {
141 	uint32_t tmp;
142 
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);
146 }
147 
lpc_enable_sio_decode(const bool addr)148 void lpc_enable_sio_decode(const bool addr)
149 {
150 	uint32_t decodes;
151 	uint32_t enable;
152 
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);
158 }
159 
lpc_enable_decode(uint32_t decodes)160 void lpc_enable_decode(uint32_t decodes)
161 {
162 	pci_write_config32(_LPCB_DEV, LPC_IO_PORT_DECODE_ENABLE, decodes);
163 }
164 
165 /*
166  * Clear all decoding to the LPC bus and erase any range registers associated
167  * with the enable bits.
168  */
lpc_disable_decodes(void)169 void lpc_disable_decodes(void)
170 {
171 	uint32_t reg;
172 
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);
178 
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);
183 }
184 
lpc_spibase(void)185 uintptr_t lpc_spibase(void)
186 {
187 	u32 base, enables;
188 
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);
193 
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. */
199 	}
200 	return base;
201 }
202 
203 /*
204  * Enable FCH to decode TPM associated Memory and IO regions
205  *
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
213  */
lpc_tpm_decode(void)214 void lpc_tpm_decode(void)
215 {
216 	u32 value;
217 
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);
221 }
222 
223 /*
224  * Enable FCH to decode TPM associated Memory and IO regions to SPI
225  *
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().
228  */
lpc_tpm_decode_spi(void)229 void lpc_tpm_decode_spi(void)
230 {
231 	/* Enable TPM decoding to FCH */
232 	lpc_tpm_decode();
233 
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);
239 }
240 
241 /*
242  * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
243  *
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.
246  *
247  * The southbridge power-on default is to map 512K ROM space.
248  *
249  */
lpc_enable_rom(void)250 void lpc_enable_rom(void)
251 {
252 	u8 reg8;
253 
254 	/*
255 	 * Decode variable LPC ROM address ranges 1 and 2.
256 	 * Bits 3-4 are not defined in any publicly available datasheet
257 	 */
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);
261 
262 	/*
263 	 * LPC ROM address range 1:
264 	 * Enable LPC ROM range mirroring start at 0x000e(0000).
265 	 */
266 	pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE1_START, 0x000e);
267 
268 	/* Enable LPC ROM range mirroring end at 0x000f(ffff). */
269 	pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE1_END, 0x000f);
270 
271 	/*
272 	 * LPC ROM address range 2:
273 	 *
274 	 * Enable LPC ROM range start at:
275 	 * 0xfff8(0000): 512KB
276 	 * 0xfff0(0000): 1MB
277 	 * 0xffe0(0000): 2MB
278 	 * 0xffc0(0000): 4MB
279 	 */
280 	pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE2_START, 0x10000
281 					- (CONFIG_COREBOOT_ROMSIZE_KB >> 6));
282 
283 	/* Enable LPC ROM range end at 0xffff(ffff). */
284 	pci_write_config16(_LPCB_DEV, ROM_ADDRESS_RANGE2_END, 0xffff);
285 }
286 
lpc_enable_spi_prefetch(void)287 void lpc_enable_spi_prefetch(void)
288 {
289 	uint32_t dword;
290 
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);
294 }
295 
lpc_disable_spi_rom_sharing(void)296 void lpc_disable_spi_rom_sharing(void)
297 {
298 	u8 byte;
299 
300 	if (!CONFIG(PROVIDES_ROM_SHARING))
301 		dead_code();
302 
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);
307 }
308 
lpc_get_spibase(void)309 uintptr_t lpc_get_spibase(void)
310 {
311 	u32 base;
312 
313 	base = pci_read_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER);
314 	base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT);
315 	return (uintptr_t)base;
316 }
317 
lpc_set_spibase(uint32_t base)318 void lpc_set_spibase(uint32_t base)
319 {
320 	uint32_t reg32;
321 
322 	reg32 = pci_read_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER);
323 
324 	reg32 &= SPI_BASE_ALIGNMENT - 1; /* preserve only reserved, enables */
325 	reg32 |= ALIGN_DOWN(base, SPI_BASE_ALIGNMENT);
326 
327 	pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER, reg32);
328 }
329 
lpc_enable_spi_rom(uint32_t enable)330 void lpc_enable_spi_rom(uint32_t enable)
331 {
332 	uint32_t reg32;
333 
334 	/* only two types of CS# enables are allowed */
335 	enable &= SPI_ROM_ENABLE | SPI_ROM_ALT_ENABLE;
336 
337 	reg32 = pci_read_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER);
338 
339 	reg32 &= ~(SPI_ROM_ENABLE | SPI_ROM_ALT_ENABLE);
340 	reg32 |= enable;
341 
342 	pci_write_config32(_LPCB_DEV, SPI_BASE_ADDRESS_REGISTER, reg32);
343 }
344 
lpc_enable_controller(void)345 static void lpc_enable_controller(void)
346 {
347 	u8 byte;
348 
349 	/* Enable LPC controller */
350 	byte = pm_read8(PM_LPC_GATING);
351 	byte |= PM_LPC_ENABLE;
352 	pm_write8(PM_LPC_GATING, byte);
353 }
354 
lpc_early_init(void)355 void lpc_early_init(void)
356 {
357 	lpc_enable_controller();
358 	lpc_disable_decodes();
359 	lpc_set_spibase(SPI_BASE_ADDRESS);
360 }
361