coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
uart.c
Go to the documentation of this file.
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_def.h>
10 #include <device/pci_ids.h>
11 #include <device/pci_ops.h>
12 #include <intelblocks/irq.h>
13 #include <intelblocks/lpss.h>
14 #include <intelblocks/uart.h>
15 #include <soc/pci_devs.h>
16 #include <soc/iomap.h>
17 #include <soc/nvs.h>
18 #include "chip.h"
19 
20 #define UART_PCI_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)
21 
22 extern const unsigned int uart_devices[];
23 extern const int uart_devices_size;
24 
25 static void uart_lpss_init(pci_devfn_t dev, uintptr_t baseaddr)
26 {
27  /* Ensure controller is in D0 state */
29 
30  /* Take UART out of reset */
31  lpss_reset_release(baseaddr);
32 
33  /* Set M and N divisor inputs and enable clock */
34  lpss_clk_update(baseaddr, CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL,
35  CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL);
36 }
37 
38 #if CONFIG(INTEL_LPSS_UART_FOR_CONSOLE)
39 uintptr_t uart_platform_base(unsigned int idx)
40 {
41  if (idx == CONFIG_UART_FOR_CONSOLE)
42  return CONFIG_CONSOLE_UART_BASE_ADDRESS;
43  return 0;
44 }
45 #endif
46 
48 {
49  int devfn;
50 
51  /*
52  * This function will get called even if INTEL_LPSS_UART_FOR_CONSOLE
53  * config option is not selected.
54  * By default return NULL in this case to avoid compilation errors.
55  */
56  if (!CONFIG(INTEL_LPSS_UART_FOR_CONSOLE))
57  return PCI_DEV_INVALID;
58 
59  if (CONFIG_UART_FOR_CONSOLE > uart_devices_size)
60  return PCI_DEV_INVALID;
61 
62  devfn = uart_devices[CONFIG_UART_FOR_CONSOLE];
63  if (devfn == PCI_DEVFN_INVALID)
64  return PCI_DEV_INVALID;
65 
66  return PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
67 }
68 
69 const struct device *uart_get_device(void)
70 {
72  if (dev == PCI_DEV_INVALID)
73  return NULL;
74 
76 }
77 
79 {
82 
83  if (dev == PCI_DEV_INVALID)
84  return false;
85 
87  if (!base)
88  return false;
89 
91  != UART_PCI_ENABLE)
92  return false;
93 
95 }
96 
98 {
99  const uint32_t baseaddr = CONFIG_CONSOLE_UART_BASE_ADDRESS;
101 
102  if (dev == PCI_DEV_INVALID)
103  return;
104 
105  /* Set UART base address */
107 
108  /* Enable memory access and bus master */
110 
111  uart_lpss_init(dev, baseaddr);
112 }
113 
114 #if ENV_RAMSTAGE
115 
116 static void uart_read_resources(struct device *dev)
117 {
119 
120  /* Set the configured UART base address for the debug port */
121  if (CONFIG(INTEL_LPSS_UART_FOR_CONSOLE) &&
123  struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
124  /* Need to set the base and size for the resource allocator. */
125  res->base = CONFIG_CONSOLE_UART_BASE_ADDRESS;
126  res->size = 0x1000;
129  }
130  /* In ACPI mode mark the decoded region as reserved */
131  if (dev->hidden) {
132  struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
133  res->flags |= IORESOURCE_RESERVE;
134  }
135 }
136 
137 /*
138  * Check if UART debug port controller needs to be initialized on resume.
139  *
140  * Returns:
141  * true = when SoC wants debug port initialization on resume
142  * false = otherwise
143  */
144 static bool pch_uart_init_debug_controller_on_resume(void)
145 {
146  struct global_nvs *gnvs = acpi_get_gnvs();
147 
148  if (gnvs)
149  return !!gnvs->uior;
150 
151  return false;
152 }
153 
154 bool uart_is_debug_controller(struct device *dev)
155 {
156  return dev == uart_get_device();
157 }
158 
159 /*
160  * This is a workaround to enable UART controller for the debug port if:
161  * 1. CONSOLE_SERIAL is not enabled in coreboot, and
162  * 2. This boot is S3 resume, and
163  * 3. SoC wants to initialize debug UART controller.
164  *
165  * This workaround is required because Linux kernel hangs on resume if console
166  * is not enabled in coreboot, but it is enabled in kernel and not suspended.
167  */
168 static bool uart_controller_needs_init(struct device *dev)
169 {
170  /*
171  * If coreboot has CONSOLE_SERIAL enabled, the skip re-initializing
172  * controller here.
173  */
174  if (CONFIG(CONSOLE_SERIAL))
175  return false;
176 
177  /* If this device does not correspond to debug port, then skip. */
178  if (!uart_is_debug_controller(dev))
179  return false;
180 
181  /* Initialize UART controller only on S3 resume. */
182  if (!acpi_is_wakeup_s3())
183  return false;
184 
185  /*
186  * check if SOC wants to initialize UART on resume
187  */
188  return pch_uart_init_debug_controller_on_resume();
189 }
190 
191 static void uart_common_enable_resources(struct device *dev)
192 {
194 
195  if (uart_controller_needs_init(dev)) {
196  uintptr_t base;
197 
198  base = pci_read_config32(dev, PCI_BASE_ADDRESS_0) & ~0xFFF;
199  if (base)
200  uart_lpss_init(PCI_BDF(dev), base);
201  }
202 }
203 
204 static void uart_acpi_write_irq(const struct device *dev)
205 {
206  if (CONFIG(SOC_INTEL_COMMON_BLOCK_IRQ)) {
207  const int irq = get_pci_devfn_irq(dev->path.pci.devfn);
208  if (irq != INVALID_IRQ) {
209  struct acpi_irq airq = (struct acpi_irq)ACPI_IRQ_LEVEL_LOW(irq);
211  }
212  }
213 }
214 
215 /*
216  * Generate an ACPI entry if the device is enabled in devicetree for the ACPI
217  * LPSS driver. In this mode the device and vendor ID reads as 0xffff, but the
218  * PCI device is still there.
219  */
220 static void uart_fill_ssdt(const struct device *dev)
221 {
222  const char *scope = acpi_device_scope(dev);
223  const char *hid = acpi_device_hid(dev);
224  struct resource *res;
225 
226  /* In ACPI mode the device is "invisible" */
227  if (!dev->hidden)
228  return;
229 
230  if (!scope || !hid)
231  return;
232 
234  if (!res)
235  return;
236 
237  /* Scope */
238  acpigen_write_scope(scope);
239 
240  /* Device */
242  acpigen_write_name_string("_HID", hid);
243  /*
244  * Advertise compatibility to Sunrise Point, as the Linux kernel doesn't support
245  * CannonPoint yet...
246  */
247  if (strcmp(hid, "INT34B8") == 0)
248  acpigen_write_name_string("_CID", "INT3448");
249  else if (strcmp(hid, "INT34B9") == 0)
250  acpigen_write_name_string("_CID", "INT3449");
251  else if (strcmp(hid, "INT34BA") == 0)
252  acpigen_write_name_string("_CID", "INT344A");
253 
255  acpigen_write_name_string("_DDN", "LPSS ACPI UART");
257 
258  /* Resources */
259  acpigen_write_name("_CRS");
261 
262  uart_acpi_write_irq(dev);
263  acpigen_write_mem32fixed(1, res->base, res->size);
264 
266 
267  acpigen_pop_len(); /* Device */
268  acpigen_pop_len(); /* Scope */
269 }
270 
271 static const char *uart_acpi_hid(const struct device *dev)
272 {
273  switch (dev->device) {
275  return "80865abc";
277  return "80865abe";
279  return "80865ac0";
281  return "808631bc";
283  return "808631be";
285  return "808631c0";
287  return "808631ee";
290  return "INT3448";
293  return "INT3449";
296  return "INT344A";
298  return "INT34B8";
300  return "INT34B9";
302  return "INT34BA";
303  default:
304  return NULL;
305  }
306 }
307 
308 static const char *uart_acpi_name(const struct device *dev)
309 {
310  switch (dev->device) {
316  return "UAR0";
322  return "UAR1";
328  return "UAR2";
330  return "UAR3";
331  default:
332  return NULL;
333  }
334 }
335 
336 static struct device_operations device_ops = {
338  .set_resources = pci_dev_set_resources,
339  .enable_resources = uart_common_enable_resources,
340  .ops_pci = &pci_dev_ops_pci,
341  .acpi_fill_ssdt = uart_fill_ssdt,
342  .acpi_hid = uart_acpi_hid,
343  .acpi_name = uart_acpi_name,
344 };
345 
346 static const unsigned short pci_device_ids[] = {
413  0,
414 };
415 
416 static const struct pci_driver pch_uart __pci_driver = {
417  .ops = &device_ops,
418  .vendor = PCI_VID_INTEL,
419  .devices = pci_device_ids,
420 };
421 
422 static void uart_enable(struct device *dev)
423 {
424  struct soc_intel_common_block_uart_config *conf = dev->chip_info;
425  dev->ops = &device_ops;
426  dev->device = conf ? conf->devid : 0;
427 }
428 
429 struct chip_operations soc_intel_common_block_uart_ops = {
430  CHIP_NAME("LPSS UART in ACPI mode")
431  .enable_dev = uart_enable
432 };
433 
434 #endif /* ENV_RAMSTAGE */
void acpi_device_write_uid(const struct device *dev)
Definition: device.c:203
void acpi_device_write_interrupt(const struct acpi_irq *irq)
Definition: device.c:209
const char * acpi_device_hid(const struct device *dev)
Definition: device.c:78
int acpi_device_status(const struct device *dev)
Definition: device.c:193
const char * acpi_device_name(const struct device *dev)
Definition: device.c:49
const char * acpi_device_scope(const struct device *dev)
Definition: device.c:158
void * acpi_get_gnvs(void)
Definition: gnvs.c:40
#define ACPI_IRQ_LEVEL_LOW(x)
Definition: acpi_device.h:111
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_scope(const char *name)
Definition: acpigen.c:326
void acpigen_write_resourcetemplate_footer(void)
Definition: acpigen.c:1165
void acpigen_write_STA(uint8_t status)
Definition: acpigen.c:783
void acpigen_write_resourcetemplate_header(void)
Definition: acpigen.c:1147
void acpigen_write_mem32fixed(int readwrite, u32 base, u32 size)
Definition: acpigen.c:1071
void acpigen_write_device(const char *name)
Definition: acpigen.c:769
void acpigen_write_name(const char *name)
Definition: acpigen.c:320
void acpigen_write_name_string(const char *name, const char *string)
Definition: acpigen.c:176
static int acpi_is_wakeup_s3(void)
Definition: acpi.h:9
static const unsigned short pci_device_ids[]
int get_pci_devfn_irq(unsigned int devfn)
Definition: irq.c:433
#define INVALID_IRQ
Definition: irq.h:10
DEVTREE_CONST struct device * pcidev_path_on_root(pci_devfn_t devfn)
Definition: device_const.c:255
struct resource * probe_resource(const struct device *dev, unsigned int index)
See if a resource structure already exists for a given index.
Definition: device_util.c:323
struct resource * find_resource(const struct device *dev, unsigned int index)
Return an existing resource structure for a given index.
Definition: device_util.c:394
@ CONFIG
Definition: dsi_common.h:201
#define CHIP_NAME(X)
Definition: device.h:32
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
struct device_operations device_ops
Definition: ioe_p2sb.c:34
void lpss_set_power_state(pci_devfn_t devfn, enum lpss_pwr_state state)
Definition: lpss.c:68
void lpss_reset_release(uintptr_t base)
Definition: lpss.c:47
bool lpss_is_controller_in_reset(uintptr_t base)
Definition: lpss.c:36
void lpss_clk_update(uintptr_t base, uint32_t clk_m_val, uint32_t clk_n_val)
Definition: lpss.c:55
@ STATE_D0
Definition: lpss.h:11
uintptr_t uart_platform_base(unsigned int idx)
Definition: uart.c:8
#define PCI_FUNC(devfn)
Definition: pci_def.h:550
#define PCI_DEV2DEVFN(sdev)
Definition: pci_def.h:553
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PCI_COMMAND
Definition: pci_def.h:10
#define PCI_SLOT(devfn)
Definition: pci_def.h:549
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
struct pci_operations pci_dev_ops_pci
Default device operation for PCI devices.
Definition: pci_device.c:911
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_DID_INTEL_GLK_UART0
Definition: pci_ids.h:3666
#define PCI_DID_INTEL_TGP_UART0
Definition: pci_ids.h:3685
#define PCI_DID_INTEL_ADP_P_UART4
Definition: pci_ids.h:3703
#define PCI_DID_INTEL_ICP_UART1
Definition: pci_ids.h:3677
#define PCI_DID_INTEL_MCC_UART1
Definition: pci_ids.h:3693
#define PCI_DID_INTEL_SPT_H_UART0
Definition: pci_ids.h:3656
#define PCI_DID_INTEL_ADP_M_N_UART2
Definition: pci_ids.h:3717
#define PCI_DID_INTEL_APL_UART2
Definition: pci_ids.h:3664
#define PCI_DID_INTEL_ADP_M_N_UART3
Definition: pci_ids.h:3718
#define PCI_DID_INTEL_ADP_P_UART3
Definition: pci_ids.h:3702
#define PCI_DID_INTEL_ADP_P_UART6
Definition: pci_ids.h:3705
#define PCI_DID_INTEL_ADP_S_UART4
Definition: pci_ids.h:3711
#define PCI_DID_INTEL_JSP_UART1
Definition: pci_ids.h:3696
#define PCI_DID_INTEL_CMP_H_UART0
Definition: pci_ids.h:3682
#define PCI_DID_INTEL_SPT_H_UART1
Definition: pci_ids.h:3657
#define PCI_DID_INTEL_TGP_H_UART3
Definition: pci_ids.h:3691
#define PCI_DID_INTEL_TGP_H_UART2
Definition: pci_ids.h:3690
#define PCI_DID_INTEL_APL_UART1
Definition: pci_ids.h:3663
#define PCI_DID_INTEL_JSP_UART0
Definition: pci_ids.h:3695
#define PCI_DID_INTEL_ADP_P_UART1
Definition: pci_ids.h:3700
#define PCI_DID_INTEL_CNL_UART1
Definition: pci_ids.h:3671
#define PCI_DID_INTEL_TGP_UART2
Definition: pci_ids.h:3687
#define PCI_DID_INTEL_UPT_H_UART0
Definition: pci_ids.h:3659
#define PCI_DID_INTEL_ICP_UART2
Definition: pci_ids.h:3678
#define PCI_DID_INTEL_CMP_UART1
Definition: pci_ids.h:3680
#define PCI_DID_INTEL_UPT_H_UART1
Definition: pci_ids.h:3660
#define PCI_DID_INTEL_ADP_P_UART5
Definition: pci_ids.h:3704
#define PCI_DID_INTEL_ADP_S_UART2
Definition: pci_ids.h:3709
#define PCI_DID_INTEL_ADP_S_UART0
Definition: pci_ids.h:3707
#define PCI_DID_INTEL_GLK_UART2
Definition: pci_ids.h:3668
#define PCI_DID_INTEL_MTL_UART1
Definition: pci_ids.h:3721
#define PCI_DID_INTEL_ADP_M_N_UART0
Definition: pci_ids.h:3715
#define PCI_DID_INTEL_SPT_UART1
Definition: pci_ids.h:3654
#define PCI_DID_INTEL_APL_UART3
Definition: pci_ids.h:3665
#define PCI_DID_INTEL_SPT_UART0
Definition: pci_ids.h:3653
#define PCI_DID_INTEL_CMP_H_UART2
Definition: pci_ids.h:3684
#define PCI_DID_INTEL_CMP_H_UART1
Definition: pci_ids.h:3683
#define PCI_DID_INTEL_CNP_H_UART1
Definition: pci_ids.h:3674
#define PCI_DID_INTEL_ADP_S_UART3
Definition: pci_ids.h:3710
#define PCI_DID_INTEL_SPT_H_UART2
Definition: pci_ids.h:3658
#define PCI_DID_INTEL_TGP_UART1
Definition: pci_ids.h:3686
#define PCI_DID_INTEL_SPT_UART2
Definition: pci_ids.h:3655
#define PCI_DID_INTEL_CNP_H_UART0
Definition: pci_ids.h:3673
#define PCI_DID_INTEL_TGP_H_UART0
Definition: pci_ids.h:3688
#define PCI_DID_INTEL_GLK_UART1
Definition: pci_ids.h:3667
#define PCI_DID_INTEL_ADP_M_N_UART1
Definition: pci_ids.h:3716
#define PCI_DID_INTEL_MCC_UART2
Definition: pci_ids.h:3694
#define PCI_DID_INTEL_GLK_UART3
Definition: pci_ids.h:3669
#define PCI_DID_INTEL_UPT_H_UART2
Definition: pci_ids.h:3661
#define PCI_DID_INTEL_JSP_UART2
Definition: pci_ids.h:3697
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
#define PCI_DID_INTEL_MTL_UART2
Definition: pci_ids.h:3722
#define PCI_DID_INTEL_ADP_P_UART2
Definition: pci_ids.h:3701
#define PCI_DID_INTEL_ADP_S_UART5
Definition: pci_ids.h:3712
#define PCI_DID_INTEL_MTL_UART0
Definition: pci_ids.h:3720
#define PCI_DID_INTEL_MCC_UART0
Definition: pci_ids.h:3692
#define PCI_DID_INTEL_CNP_H_UART2
Definition: pci_ids.h:3675
#define PCI_DID_INTEL_CNL_UART0
Definition: pci_ids.h:3670
#define PCI_DID_INTEL_ADP_S_UART6
Definition: pci_ids.h:3713
#define PCI_DID_INTEL_CNL_UART2
Definition: pci_ids.h:3672
#define PCI_DID_INTEL_ICP_UART0
Definition: pci_ids.h:3676
#define PCI_DID_INTEL_TGP_H_UART1
Definition: pci_ids.h:3689
#define PCI_DID_INTEL_ADP_P_UART0
Definition: pci_ids.h:3699
#define PCI_DID_INTEL_ADP_S_UART1
Definition: pci_ids.h:3708
#define PCI_DID_INTEL_CMP_UART2
Definition: pci_ids.h:3681
#define PCI_DID_INTEL_CMP_UART0
Definition: pci_ids.h:3679
#define PCI_DID_INTEL_APL_UART0
Definition: pci_ids.h:3662
static __always_inline uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg)
Definition: pci_io_cfg.h:92
static __always_inline uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg)
Definition: pci_io_cfg.h:86
static __always_inline void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value)
Definition: pci_io_cfg.h:104
static __always_inline void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value)
Definition: pci_io_cfg.h:110
#define PCI_BDF(dev)
Definition: pci_type.h:28
#define PCI_DEV(SEGBUS, DEV, FN)
Definition: pci_type.h:14
u32 pci_devfn_t
Definition: pci_type.h:8
#define PCI_DEV_INVALID
Definition: pci_type.h:19
#define PCI_DEVFN_INVALID
Definition: pci_type.h:20
#define IORESOURCE_RESERVE
Definition: resource.h:30
#define IORESOURCE_MEM
Definition: resource.h:10
#define IORESOURCE_ASSIGNED
Definition: resource.h:34
#define IORESOURCE_FIXED
Definition: resource.h:36
struct global_nvs * gnvs
static void uart_enable(struct device *dev)
Definition: uart.c:64
static void uart_read_resources(struct device *dev)
Definition: uart.c:88
static const char * uart_acpi_name(const struct device *dev)
Definition: uart.c:51
uintptr_t base
Definition: uart.c:17
static const struct pci_driver soc_cavium_uart __pci_driver
Definition: uart.c:22
const int uart_devices_size
Definition: uart.c:18
const unsigned int uart_devices[]
Definition: uart.c:12
bool uart_is_debug_controller(struct device *dev)
static void uart_lpss_init(pci_devfn_t dev, uintptr_t baseaddr)
Definition: uart.c:25
const struct device * uart_get_device(void)
Definition: uart.c:69
#define UART_PCI_ENABLE
Definition: uart.c:20
bool uart_is_controller_initialized(void)
Definition: uart.c:78
void uart_bootblock_init(void)
Definition: uart.c:97
static pci_devfn_t uart_console_get_pci_bdf(void)
Definition: uart.c:47
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
int strcmp(const char *s1, const char *s2)
Definition: string.c:103
void(* read_resources)(struct device *dev)
Definition: device.h:39
struct pci_path pci
Definition: path.h:116
Definition: device.h:107
unsigned int hidden
Definition: device.h:127
struct device_path path
Definition: device.h:115
struct device_operations * ops
Definition: device.h:143
unsigned int device
Definition: device.h:117
DEVTREE_CONST void * chip_info
Definition: device.h:164
Definition: nvs.h:14
uint8_t uior
Definition: nvs.h:29
unsigned int devfn
Definition: path.h:54
unsigned long flags
Definition: resource.h:49
resource_t base
Definition: resource.h:45
resource_t size
Definition: resource.h:46