xref: /aosp_15_r20/external/coreboot/src/soc/intel/common/block/uart/uart.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <acpi/acpigen.h>
5 #include <acpi/acpi_gnvs.h>
6 #include <console/uart.h>
7 #include <device/device.h>
8 #include <device/pci.h>
9 #include <device/pci_ids.h>
10 #include <device/pci_ops.h>
11 #include <intelblocks/irq.h>
12 #include <intelblocks/lpss.h>
13 #include <intelblocks/uart.h>
14 #include <soc/pci_devs.h>
15 #include <soc/iomap.h>
16 #include <soc/nvs.h>
17 
18 #define UART_PCI_ENABLE	(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)
19 
20 extern const unsigned int uart_devices[];
21 extern const int uart_devices_size;
22 
uart_lpss_init(pci_devfn_t dev,uintptr_t baseaddr)23 static void uart_lpss_init(pci_devfn_t dev, uintptr_t baseaddr)
24 {
25 	/* Ensure controller is in D0 state */
26 	lpss_set_power_state(dev, STATE_D0);
27 
28 	/* Take UART out of reset */
29 	lpss_reset_release(baseaddr);
30 
31 	/* Set M and N divisor inputs and enable clock */
32 	lpss_clk_update(baseaddr, CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL,
33 			CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL);
34 }
35 
36 #if CONFIG(INTEL_LPSS_UART_FOR_CONSOLE)
uart_platform_base(unsigned int idx)37 uintptr_t uart_platform_base(unsigned int idx)
38 {
39 	if (idx == CONFIG_UART_FOR_CONSOLE)
40 		return CONFIG_CONSOLE_UART_BASE_ADDRESS;
41 	return 0;
42 }
43 #endif
44 
uart_console_get_pci_bdf(void)45 static pci_devfn_t uart_console_get_pci_bdf(void)
46 {
47 	int devfn;
48 
49 	/*
50 	 * This function will get called even if INTEL_LPSS_UART_FOR_CONSOLE
51 	 * config option is not selected.
52 	 * By default return NULL in this case to avoid compilation errors.
53 	 */
54 	if (!CONFIG(INTEL_LPSS_UART_FOR_CONSOLE))
55 		return PCI_DEV_INVALID;
56 
57 	if (CONFIG_UART_FOR_CONSOLE > uart_devices_size)
58 		return PCI_DEV_INVALID;
59 
60 	devfn = uart_devices[CONFIG_UART_FOR_CONSOLE];
61 	if (devfn == PCI_DEVFN_INVALID)
62 		return PCI_DEV_INVALID;
63 
64 	return PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
65 }
66 
uart_get_device(void)67 const struct device *uart_get_device(void)
68 {
69 	pci_devfn_t dev = uart_console_get_pci_bdf();
70 	if (dev == PCI_DEV_INVALID)
71 		return NULL;
72 
73 	return pcidev_path_on_root(PCI_DEV2DEVFN(dev));
74 }
75 
uart_is_controller_initialized(void)76 bool uart_is_controller_initialized(void)
77 {
78 	uintptr_t base;
79 	pci_devfn_t dev = uart_console_get_pci_bdf();
80 
81 	if (dev == PCI_DEV_INVALID)
82 		return false;
83 
84 	base = pci_s_read_config32(dev, PCI_BASE_ADDRESS_0) & ~0xFFF;
85 	if (!base)
86 		return false;
87 
88 	if ((pci_s_read_config16(dev, PCI_COMMAND) & UART_PCI_ENABLE)
89 	    != UART_PCI_ENABLE)
90 		return false;
91 
92 	return !lpss_is_controller_in_reset(base);
93 }
94 
uart_bootblock_init(void)95 void uart_bootblock_init(void)
96 {
97 	const uint32_t baseaddr = CONFIG_CONSOLE_UART_BASE_ADDRESS;
98 	pci_devfn_t dev = uart_console_get_pci_bdf();
99 
100 	if (dev == PCI_DEV_INVALID)
101 		return;
102 
103 	/* Set UART base address */
104 	pci_s_write_config32(dev, PCI_BASE_ADDRESS_0, baseaddr);
105 
106 	/* Enable memory access and bus master */
107 	pci_s_write_config16(dev, PCI_COMMAND, UART_PCI_ENABLE);
108 
109 	uart_lpss_init(dev, baseaddr);
110 }
111 
112 #if ENV_RAMSTAGE
113 
uart_read_resources(struct device * dev)114 static void uart_read_resources(struct device *dev)
115 {
116 	pci_dev_read_resources(dev);
117 
118 	/* Set the configured UART base address for the debug port */
119 	if (CONFIG(INTEL_LPSS_UART_FOR_CONSOLE) &&
120 	    uart_is_debug_controller(dev)) {
121 		struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
122 		/* Need to set the base and size for the resource allocator. */
123 		res->base = CONFIG_CONSOLE_UART_BASE_ADDRESS;
124 		res->size = 0x1000;
125 		res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
126 				IORESOURCE_FIXED;
127 	}
128 	/* In ACPI mode mark the decoded region as reserved */
129 	if (dev->hidden) {
130 		struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
131 		res->flags |= IORESOURCE_RESERVE;
132 	}
133 }
134 
135 /*
136  * Check if UART debug port controller needs to be initialized on resume.
137  *
138  * Returns:
139  * true = when SoC wants debug port initialization on resume
140  * false = otherwise
141  */
pch_uart_init_debug_controller_on_resume(void)142 static bool pch_uart_init_debug_controller_on_resume(void)
143 {
144 	struct global_nvs *gnvs = acpi_get_gnvs();
145 
146 	if (gnvs)
147 		return !!gnvs->uior;
148 
149 	return false;
150 }
151 
uart_is_debug_controller(struct device * dev)152 bool uart_is_debug_controller(struct device *dev)
153 {
154 	return dev == uart_get_device();
155 }
156 
157 /*
158  * This is a workaround to enable UART controller for the debug port if:
159  * 1. CONSOLE_SERIAL is not enabled in coreboot, and
160  * 2. This boot is S3 resume, and
161  * 3. SoC wants to initialize debug UART controller.
162  *
163  * This workaround is required because Linux kernel hangs on resume if console
164  * is not enabled in coreboot, but it is enabled in kernel and not suspended.
165  */
uart_controller_needs_init(struct device * dev)166 static bool uart_controller_needs_init(struct device *dev)
167 {
168 	/*
169 	 * If coreboot has CONSOLE_SERIAL enabled, the skip re-initializing
170 	 * controller here.
171 	 */
172 	if (CONFIG(CONSOLE_SERIAL))
173 		return false;
174 
175 	/* If this device does not correspond to debug port, then skip. */
176 	if (!uart_is_debug_controller(dev))
177 		return false;
178 
179 	/* Initialize UART controller only on S3 resume. */
180 	if (!acpi_is_wakeup_s3())
181 		return false;
182 
183 	/*
184 	 * check if SOC wants to initialize UART on resume
185 	 */
186 	return pch_uart_init_debug_controller_on_resume();
187 }
188 
uart_common_enable_resources(struct device * dev)189 static void uart_common_enable_resources(struct device *dev)
190 {
191 	pci_dev_enable_resources(dev);
192 
193 	if (uart_controller_needs_init(dev)) {
194 		uintptr_t base;
195 
196 		base = pci_read_config32(dev, PCI_BASE_ADDRESS_0) & ~0xFFF;
197 		if (base)
198 			uart_lpss_init(PCI_BDF(dev), base);
199 	}
200 }
201 
uart_acpi_write_irq(const struct device * dev)202 static void uart_acpi_write_irq(const struct device *dev)
203 {
204 	if (CONFIG(SOC_INTEL_COMMON_BLOCK_IRQ)) {
205 		const int irq = get_pci_devfn_irq(dev->path.pci.devfn);
206 		if (irq != INVALID_IRQ) {
207 			struct acpi_irq airq = (struct acpi_irq)ACPI_IRQ_LEVEL_LOW(irq);
208 			acpi_device_write_interrupt(&airq);
209 		}
210 	}
211 }
212 
213 /*
214  * Generate an ACPI entry if the device is enabled in devicetree for the ACPI
215  * LPSS driver. In this mode the device and vendor ID reads as 0xffff, but the
216  * PCI device is still there.
217  */
uart_fill_ssdt(const struct device * dev)218 static void uart_fill_ssdt(const struct device *dev)
219 {
220 	const char *scope = acpi_device_scope(dev);
221 	const char *hid = acpi_device_hid(dev);
222 	struct resource *res;
223 
224 	/* In ACPI mode the device is "invisible" */
225 	if (!dev->hidden)
226 		return;
227 
228 	if (!scope || !hid)
229 		return;
230 
231 	res = probe_resource(dev, PCI_BASE_ADDRESS_0);
232 	if (!res)
233 		return;
234 
235 	/* Scope */
236 	acpigen_write_scope(scope);
237 
238 	/* Device */
239 	acpigen_write_device(acpi_device_name(dev));
240 	acpigen_write_name_string("_HID", hid);
241 	/*
242 	 * Advertise compatibility to Sunrise Point, as the Linux kernel doesn't support
243 	 * CannonPoint yet...
244 	 */
245 	if (strcmp(hid, "INT34B8") == 0)
246 		acpigen_write_name_string("_CID", "INT3448");
247 	else if (strcmp(hid, "INT34B9") == 0)
248 		acpigen_write_name_string("_CID", "INT3449");
249 	else if (strcmp(hid, "INT34BA") == 0)
250 		acpigen_write_name_string("_CID", "INT344A");
251 
252 	acpi_device_write_uid(dev);
253 	acpigen_write_name_string("_DDN", "LPSS ACPI UART");
254 
255 	/* Do not hide the UART device from the OS */
256 	acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
257 
258 	/* Resources */
259 	acpigen_write_name("_CRS");
260 	acpigen_write_resourcetemplate_header();
261 
262 	uart_acpi_write_irq(dev);
263 	acpigen_write_mem32fixed(1, res->base, res->size);
264 
265 	acpigen_write_resourcetemplate_footer();
266 
267 	acpigen_pop_len(); /* Device */
268 	acpigen_pop_len(); /* Scope */
269 }
270 
uart_acpi_hid(const struct device * dev)271 static const char *uart_acpi_hid(const struct device *dev)
272 {
273 	switch (dev->device) {
274 	case PCI_DID_INTEL_APL_UART0:
275 		return "80865abc";
276 	case PCI_DID_INTEL_APL_UART1:
277 		return "80865abe";
278 	case PCI_DID_INTEL_APL_UART2:
279 		return "80865ac0";
280 	case PCI_DID_INTEL_GLK_UART0:
281 		return  "808631bc";
282 	case PCI_DID_INTEL_GLK_UART1:
283 		return  "808631be";
284 	case PCI_DID_INTEL_GLK_UART2:
285 		return  "808631c0";
286 	case PCI_DID_INTEL_GLK_UART3:
287 		return  "808631ee";
288 	case PCI_DID_INTEL_SPT_UART0:
289 	case PCI_DID_INTEL_SPT_H_UART0:
290 		return "INT3448";
291 	case PCI_DID_INTEL_SPT_UART1:
292 	case PCI_DID_INTEL_SPT_H_UART1:
293 		return "INT3449";
294 	case PCI_DID_INTEL_SPT_UART2:
295 	case PCI_DID_INTEL_SPT_H_UART2:
296 		return "INT344A";
297 	case PCI_DID_INTEL_CNP_H_UART0:
298 		return "INT34B8";
299 	case PCI_DID_INTEL_CNP_H_UART1:
300 		return "INT34B9";
301 	case PCI_DID_INTEL_CNP_H_UART2:
302 		return "INT34BA";
303 	default:
304 		return NULL;
305 	}
306 }
307 
uart_acpi_name(const struct device * dev)308 static const char *uart_acpi_name(const struct device *dev)
309 {
310 	switch (dev->device) {
311 	case PCI_DID_INTEL_PTL_UART0:
312 	case PCI_DID_INTEL_LNL_UART0:
313 	case PCI_DID_INTEL_ADP_P_UART0:
314 	case PCI_DID_INTEL_APL_UART0:
315 	case PCI_DID_INTEL_GLK_UART0:
316 	case PCI_DID_INTEL_SPT_UART0:
317 	case PCI_DID_INTEL_SPT_H_UART0:
318 	case PCI_DID_INTEL_CNP_H_UART0:
319 		return "UAR0";
320 	case PCI_DID_INTEL_PTL_UART1:
321 	case PCI_DID_INTEL_LNL_UART1:
322 	case PCI_DID_INTEL_ADP_P_UART1:
323 	case PCI_DID_INTEL_APL_UART1:
324 	case PCI_DID_INTEL_GLK_UART1:
325 	case PCI_DID_INTEL_SPT_UART1:
326 	case PCI_DID_INTEL_SPT_H_UART1:
327 	case PCI_DID_INTEL_CNP_H_UART1:
328 		return "UAR1";
329 	case PCI_DID_INTEL_PTL_UART2:
330 	case PCI_DID_INTEL_LNL_UART2:
331 	case PCI_DID_INTEL_ADP_P_UART2:
332 	case PCI_DID_INTEL_APL_UART2:
333 	case PCI_DID_INTEL_GLK_UART2:
334 	case PCI_DID_INTEL_SPT_UART2:
335 	case PCI_DID_INTEL_SPT_H_UART2:
336 	case PCI_DID_INTEL_CNP_H_UART2:
337 		return "UAR2";
338 	case PCI_DID_INTEL_ADP_P_UART3:
339 	case PCI_DID_INTEL_GLK_UART3:
340 		return "UAR3";
341 	default:
342 		return NULL;
343 	}
344 }
345 
346 struct device_operations uart_ops = {
347 	.read_resources		= uart_read_resources,
348 	.set_resources		= pci_dev_set_resources,
349 	.enable_resources	= uart_common_enable_resources,
350 	.ops_pci		= &pci_dev_ops_pci,
351 	.acpi_fill_ssdt		= uart_fill_ssdt,
352 	.acpi_hid		= uart_acpi_hid,
353 	.acpi_name		= uart_acpi_name,
354 };
355 
356 static const unsigned short pci_device_ids[] = {
357 	PCI_DID_INTEL_PTL_UART0,
358 	PCI_DID_INTEL_PTL_UART1,
359 	PCI_DID_INTEL_PTL_UART2,
360 	PCI_DID_INTEL_LNL_UART0,
361 	PCI_DID_INTEL_LNL_UART1,
362 	PCI_DID_INTEL_LNL_UART2,
363 	PCI_DID_INTEL_MTL_UART0,
364 	PCI_DID_INTEL_MTL_UART1,
365 	PCI_DID_INTEL_MTL_UART2,
366 	PCI_DID_INTEL_APL_UART0,
367 	PCI_DID_INTEL_APL_UART1,
368 	PCI_DID_INTEL_APL_UART2,
369 	PCI_DID_INTEL_APL_UART3,
370 	PCI_DID_INTEL_CNL_UART0,
371 	PCI_DID_INTEL_CNL_UART1,
372 	PCI_DID_INTEL_CNL_UART2,
373 	PCI_DID_INTEL_GLK_UART0,
374 	PCI_DID_INTEL_GLK_UART1,
375 	PCI_DID_INTEL_GLK_UART2,
376 	PCI_DID_INTEL_GLK_UART3,
377 	PCI_DID_INTEL_CNP_H_UART0,
378 	PCI_DID_INTEL_CNP_H_UART1,
379 	PCI_DID_INTEL_CNP_H_UART2,
380 	PCI_DID_INTEL_ICP_UART0,
381 	PCI_DID_INTEL_ICP_UART1,
382 	PCI_DID_INTEL_ICP_UART2,
383 	PCI_DID_INTEL_CMP_UART0,
384 	PCI_DID_INTEL_CMP_UART1,
385 	PCI_DID_INTEL_CMP_UART2,
386 	PCI_DID_INTEL_CMP_H_UART0,
387 	PCI_DID_INTEL_CMP_H_UART1,
388 	PCI_DID_INTEL_CMP_H_UART2,
389 	PCI_DID_INTEL_TGP_UART0,
390 	PCI_DID_INTEL_TGP_UART1,
391 	PCI_DID_INTEL_TGP_UART2,
392 	PCI_DID_INTEL_TGP_H_UART0,
393 	PCI_DID_INTEL_TGP_H_UART1,
394 	PCI_DID_INTEL_TGP_H_UART2,
395 	PCI_DID_INTEL_TGP_H_UART3,
396 	PCI_DID_INTEL_MCC_UART0,
397 	PCI_DID_INTEL_MCC_UART1,
398 	PCI_DID_INTEL_MCC_UART2,
399 	PCI_DID_INTEL_JSP_UART0,
400 	PCI_DID_INTEL_JSP_UART1,
401 	PCI_DID_INTEL_JSP_UART2,
402 	PCI_DID_INTEL_ADP_S_UART0,
403 	PCI_DID_INTEL_ADP_S_UART1,
404 	PCI_DID_INTEL_ADP_S_UART2,
405 	PCI_DID_INTEL_ADP_S_UART3,
406 	PCI_DID_INTEL_ADP_S_UART4,
407 	PCI_DID_INTEL_ADP_S_UART5,
408 	PCI_DID_INTEL_ADP_S_UART6,
409 	PCI_DID_INTEL_ADP_P_UART0,
410 	PCI_DID_INTEL_ADP_P_UART1,
411 	PCI_DID_INTEL_ADP_P_UART2,
412 	PCI_DID_INTEL_ADP_P_UART3,
413 	PCI_DID_INTEL_ADP_P_UART4,
414 	PCI_DID_INTEL_ADP_P_UART5,
415 	PCI_DID_INTEL_ADP_P_UART6,
416 	PCI_DID_INTEL_ADP_M_N_UART0,
417 	PCI_DID_INTEL_ADP_M_N_UART1,
418 	PCI_DID_INTEL_ADP_M_N_UART2,
419 	PCI_DID_INTEL_ADP_M_N_UART3,
420 	PCI_DID_INTEL_RPP_S_UART0,
421 	PCI_DID_INTEL_RPP_S_UART1,
422 	PCI_DID_INTEL_RPP_S_UART2,
423 	PCI_DID_INTEL_RPP_S_UART3,
424 	0,
425 };
426 
427 static const struct pci_driver pch_uart __pci_driver = {
428 	.ops		= &uart_ops,
429 	.vendor		= PCI_VID_INTEL,
430 	.devices	= pci_device_ids,
431 };
432 #endif /* ENV_RAMSTAGE */
433