coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
lpc.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/ioapic.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pnp.h>
8 #include <device/pci_ids.h>
9 #include <device/pci_ops.h>
10 #include <device/pci_def.h>
11 #include <pc80/mc146818rtc.h>
12 #include <pc80/isa-dma.h>
13 #include <arch/ioapic.h>
14 #include <pc80/i8254.h>
15 #include <pc80/i8259.h>
16 #include <amdblocks/acpi.h>
17 #include <amdblocks/acpimmio.h>
18 #include <amdblocks/espi.h>
19 #include <amdblocks/ioapic.h>
20 #include <amdblocks/lpc.h>
21 #include <soc/iomap.h>
22 #include <soc/lpc.h>
23 #include <soc/southbridge.h>
24 
25 static void setup_serirq(void)
26 {
27  u8 byte;
28 
29  /* Set up SERIRQ, enable continuous mode */
30  byte = PM_SERIRQ_NUM_BITS_21;
31  if (!CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI))
32  byte |= PM_SERIRQ_ENABLE;
33  if (!CONFIG(SERIRQ_CONTINUOUS_MODE))
34  byte |= PM_SERIRQ_MODE;
35 
37 }
38 
39 static void fch_ioapic_init(void)
40 {
43 }
44 
45 static void lpc_init(struct device *dev)
46 {
47  u8 byte;
48 
49  /* Initialize isa dma */
50  isa_dma_init();
51 
52  /* Enable DMA transaction on the LPC bus */
53  byte = pci_read_config8(dev, LPC_PCI_CONTROL);
54  byte |= LEGACY_DMA_EN;
56 
57  /* Disable the timeout mechanism on LPC */
61 
62  /* Disable LPC MSI Capability */
64  /* BIT 1 is not defined in public datasheet. */
65  byte &= ~(1 << 1);
66 
68 
69  /*
70  * Enable hand-instance of the pulse generator and SPI prefetch from
71  * host (earlier is recommended for boot speed).
72  */
76 
78 
79  /*
80  * Initialize the real time clock.
81  * The 0 argument tells cmos_init not to
82  * update CMOS unless it is invalid.
83  * 1 tells cmos_init to always initialize the CMOS.
84  */
85  cmos_init(0);
86 
87  /* Initialize i8259 pic */
88  setup_i8259();
89 
90  /* Initialize i8254 timers */
91  setup_i8254();
92 
93  setup_serirq();
94 
97 }
98 
99 static void lpc_read_resources(struct device *dev)
100 {
101  struct resource *res;
102 
103  /* Get the normal pci resources of this device */
105 
106  /* Add an extra subtractive resource for both memory and I/O. */
107  res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
108  res->base = 0;
109  res->size = 0x1000;
112 
113  res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
114  res->base = FLASH_BASE_ADDR;
115  res->size = CONFIG_ROM_SIZE;
118 
119  /* Add a memory resource for the SPI BAR. */
122 
123  res = new_resource(dev, 3); /* IOAPIC */
124  res->base = IO_APIC_ADDR;
125  res->size = 0x00001000;
127 
128  compact_resources(dev);
129 }
130 
131 static void lpc_set_resources(struct device *dev)
132 {
133  struct resource *res;
134  u32 spi_enable_bits;
135 
136  /* Special case. The SpiRomEnable and other enables should STAY set. */
137  res = find_resource(dev, 2);
138  spi_enable_bits = pci_read_config32(dev, SPI_BASE_ADDRESS_REGISTER);
139  spi_enable_bits &= SPI_BASE_ALIGNMENT - 1;
141  res->base | spi_enable_bits);
142 
144 }
145 
146 static void configure_child_lpc_windows(struct device *dev, struct device *child)
147 {
148  struct resource *res;
149  u32 base, end;
150  u32 rsize = 0, set = 0, set_x = 0;
151  int wideio_index;
152  u32 reg, reg_x;
153 
156 
157  /*
158  * Be a bit relaxed, tolerate that LPC region might be bigger than
159  * resource we try to fit, do it like this for all regions < 16 bytes.
160  * If there is a resource > 16 bytes it must be 512 bytes to be able
161  * to allocate the fresh LPC window.
162  *
163  * AGESA and early initialization can set a wide IO port. This code
164  * will verify if required region was previously set and will avoid
165  * setting a new wide IO resource if one is already set.
166  */
167 
168  for (res = child->resource_list; res; res = res->next) {
169  if (!(res->flags & IORESOURCE_IO))
170  continue;
171  base = res->base;
172  end = resource_end(res);
174  "Southbridge LPC decode:%s, base=0x%08x, end=0x%08x\n",
175  dev_path(child), base, end);
176  /* find a resource size */
177  switch (base) {
178  case 0x60: /* KB */
179  case 0x64: /* MS */
180  set |= DECODE_ENABLE_KBC_PORT;
181  rsize = 1;
182  break;
183  case 0x3f8: /* COM1 */
185  rsize = 8;
186  break;
187  case 0x2f8: /* COM2 */
189  rsize = 8;
190  break;
191  case 0x378: /* Parallel 1 */
193  /* enable 0x778 for ECP mode */
195  rsize = 8;
196  break;
197  case 0x3f0: /* FD0 */
199  rsize = 8;
200  break;
201  case 0x220: /* 0x220 - 0x227 */
203  rsize = 8;
204  break;
205  case 0x228: /* 0x228 - 0x22f */
207  rsize = 8;
208  break;
209  case 0x238: /* 0x238 - 0x23f */
211  rsize = 8;
212  break;
213  case 0x300: /* 0x300 - 0x301 */
215  rsize = 2;
216  break;
217  case 0x400:
218  set_x |= DECODE_IO_PORT_ENABLE0;
219  rsize = 0x40;
220  break;
221  case 0x480:
222  set_x |= DECODE_IO_PORT_ENABLE1;
223  rsize = 0x40;
224  break;
225  case 0x500:
226  set_x |= DECODE_IO_PORT_ENABLE2;
227  rsize = 0x40;
228  break;
229  case 0x580:
230  set_x |= DECODE_IO_PORT_ENABLE3;
231  rsize = 0x40;
232  break;
233  case 0x4700:
234  set_x |= DECODE_IO_PORT_ENABLE5;
235  rsize = 0xc;
236  break;
237  case 0xfd60:
238  set_x |= DECODE_IO_PORT_ENABLE6;
239  rsize = 16;
240  break;
241  default:
242  rsize = 0;
243  wideio_index = lpc_find_wideio_range(base, res->size);
244  if (wideio_index != WIDEIO_RANGE_ERROR) {
245  rsize = lpc_wideio_size(wideio_index);
246  printk(BIOS_DEBUG, "Covered by wideIO");
247  printk(BIOS_DEBUG, " %d\n", wideio_index);
248  }
249  }
250  /* check if region found and matches the enable */
251  if (res->size <= rsize) {
252  reg |= set;
253  reg_x |= set_x;
254  /* check if we can fit resource in variable range */
255  } else {
256  wideio_index = lpc_set_wideio_range(base, res->size);
257  if (wideio_index != WIDEIO_RANGE_ERROR) {
258  /* preserve wide IO related bits. */
259  reg_x = pci_read_config32(dev,
262  "Range assigned to wide IO %d\n",
263  wideio_index);
264  } else {
266  "cannot fit LPC decode region:");
268  "%s, base = 0x%08x, end = 0x%08x\n",
269  dev_path(child), base, end);
270  }
271  }
272  }
273 
276 }
277 
278 static void configure_child_espi_windows(struct device *child)
279 {
280  struct resource *res;
281 
282  for (res = child->resource_list; res; res = res->next) {
283  if (res->flags & IORESOURCE_IO)
284  espi_open_io_window(res->base, res->size);
285  else if (res->flags & IORESOURCE_MEM)
286  espi_open_mmio_window(res->base, res->size);
287  }
288 }
289 
290 static void lpc_enable_children_resources(struct device *dev)
291 {
292  struct bus *link;
293  struct device *child;
294 
295  for (link = dev->link_list; link; link = link->next) {
296  for (child = link->children; child; child = child->sibling) {
297  if (!child->enabled)
298  continue;
299  if (child->path.type != DEVICE_PATH_PNP)
300  continue;
301  if (CONFIG(SOC_AMD_COMMON_BLOCK_USE_ESPI))
303  else
304  configure_child_lpc_windows(dev, child);
305  }
306  }
307 }
308 
309 static void lpc_enable_resources(struct device *dev)
310 {
313 }
314 
315 #if CONFIG(HAVE_ACPI_TABLES)
316 static const char *lpc_acpi_name(const struct device *dev)
317 {
318  return "LPCB";
319 }
320 #endif
321 
322 static struct device_operations lpc_ops = {
324  .set_resources = lpc_set_resources,
325  .enable_resources = lpc_enable_resources,
326 #if CONFIG(HAVE_ACPI_TABLES)
327  .acpi_name = lpc_acpi_name,
328  .write_acpi_tables = southbridge_write_acpi_tables,
329 #endif
330  .init = lpc_init,
331  .scan_bus = scan_static_bus,
332  .ops_pci = &pci_dev_ops_pci,
333 };
334 
335 static const unsigned short pci_device_ids[] = {
336  /* PCI device ID is used on all discrete FCHs and Family 16h Models 00h-3Fh */
338  /* PCI device ID is used on all integrated FCHs except Family 16h Models 00h-3Fh */
340  0
341 };
342 static const struct pci_driver lpc_driver __pci_driver = {
343  .ops = &lpc_ops,
344  .vendor = PCI_VID_AMD,
345  .devices = pci_device_ids,
346 };
static void pm_write8(uint8_t reg, uint8_t value)
Definition: acpimmio.h:181
#define SPI_BASE_ADDRESS
Definition: iomap.h:8
#define FLASH_BASE_ADDR
Definition: io.h:13
#define VIO_APIC_VADDR
Definition: ioapic.h:7
#define IO_APIC_ADDR
Definition: ioapic.h:6
void setup_ioapic(void *ioapic_base, u8 ioapic_id)
Definition: ioapic.c:160
#define KiB
Definition: helpers.h:75
#define PM_SERIRQ_MODE
Definition: southbridge.h:24
#define PM_SERIRQ_ENABLE
Definition: southbridge.h:25
#define PM_SERIRQ_NUM_BITS_21
Definition: southbridge.h:20
#define PM_SERIRQ_CONF
Definition: southbridge.h:15
#define printk(level,...)
Definition: stdlib.h:16
void fixed_mem_resource(struct device *dev, unsigned long index, unsigned long basek, unsigned long sizek, unsigned long type)
Definition: device_util.c:825
struct resource * new_resource(struct device *dev, unsigned int index)
See if a resource structure already exists for a given index and if not allocate one.
Definition: device_util.c:346
void compact_resources(struct device *dev)
See if we have unused but allocated resource structures.
Definition: device_util.c:302
resource_t resource_end(const struct resource *resource)
Compute the maximum address that is part of a resource.
Definition: device_util.c:445
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
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
@ CONFIG
Definition: dsi_common.h:201
void setup_i8254(void)
Definition: i8254.c:10
void setup_i8259(void)
Definition: i8259.c:46
static __always_inline void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Definition: pci_ops.h:76
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline u8 pci_read_config8(const struct device *dev, u16 reg)
Definition: pci_ops.h:46
static __always_inline void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Definition: pci_ops.h:64
void isa_dma_init(void)
Definition: isa-dma.c:35
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
void cmos_check_update_date(void)
Definition: mc146818rtc.c:192
void cmos_init(bool invalid)
Definition: mc146818rtc.c:156
void fch_enable_ioapic_decode(void)
Definition: mmio_util.c:84
void fch_configure_hpet(void)
Definition: mmio_util.c:89
@ DEVICE_PATH_PNP
Definition: path.h:10
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_VID_AMD
Definition: pci_ids.h:496
#define PCI_DID_AMD_SB900_LPC
Definition: pci_ids.h:517
#define PCI_DID_AMD_CZ_LPC
Definition: pci_ids.h:578
#define IORESOURCE_MEM
Definition: resource.h:10
#define IORESOURCE_SUBTRACTIVE
Definition: resource.h:24
#define IORESOURCE_ASSIGNED
Definition: resource.h:34
#define IORESOURCE_IO
Definition: resource.h:9
#define IOINDEX_SUBTRACTIVE(IDX, LINK)
Definition: resource.h:57
#define IORESOURCE_FIXED
Definition: resource.h:36
void scan_static_bus(struct device *bus)
Definition: root_device.c:89
#define SPI_BASE_ALIGNMENT
Definition: lpc.h:13
#define SPI_BASE_ADDRESS_REGISTER
Definition: lpc.h:12
uintptr_t base
Definition: uart.c:17
enum cb_err espi_open_io_window(uint16_t base, size_t size)
Definition: espi_util.c:234
enum cb_err espi_open_mmio_window(uint32_t base, size_t size)
Definition: espi_util.c:286
#define FCH_IOAPIC_ID
Definition: ioapic.h:7
#define DECODE_IO_PORT_ENABLE5
Definition: lpc.h:54
#define DECODE_ENABLE_FDC_PORT0
Definition: lpc.h:43
#define DECODE_IO_PORT_ENABLE6
Definition: lpc.h:53
uint16_t lpc_wideio_size(int index)
Find the size of a particular wide IO.
Definition: lpc_util.c:54
#define LPC_PCI_CONTROL
Definition: lpc.h:9
#define LPC_IO_PORT_DECODE_ENABLE
Definition: lpc.h:16
#define PREFETCH_EN_SPI_FROM_HOST
Definition: lpc.h:128
#define DECODE_ENABLE_SERIAL_PORT2
Definition: lpc.h:25
#define DECODE_ENABLE_MIDI_PORT0
Definition: lpc.h:35
#define DECODE_IO_PORT_ENABLE3
Definition: lpc.h:57
#define LPC_MISC_CONTROL_BITS
Definition: lpc.h:97
#define T_START_ENH
Definition: lpc.h:129
#define DECODE_ENABLE_SERIAL_PORT3
Definition: lpc.h:26
#define DECODE_IO_PORT_ENABLE2
Definition: lpc.h:58
#define DECODE_ENABLE_SERIAL_PORT1
Definition: lpc.h:24
#define LEGACY_DMA_EN
Definition: lpc.h:10
#define WIDEIO_RANGE_ERROR
Definition: lpc.h:70
#define DECODE_IO_PORT_ENABLE1
Definition: lpc.h:59
#define DECODE_ENABLE_PARALLEL_PORT1
Definition: lpc.h:18
#define LPC_SYNC_TIMEOUT_COUNT_ENABLE
Definition: lpc.h:62
#define LPC_IO_OR_MEM_DECODE_ENABLE
Definition: lpc.h:50
#define DECODE_ENABLE_KBC_PORT
Definition: lpc.h:46
#define DECODE_ENABLE_SERIAL_PORT4
Definition: lpc.h:27
#define DECODE_IO_PORT_ENABLE0
Definition: lpc.h:60
#define DECODE_ENABLE_PARALLEL_PORT0
Definition: lpc.h:17
int lpc_find_wideio_range(uint16_t start, uint16_t size)
Identify if any LPC wide IO is covering the IO range.
Definition: lpc_util.c:80
#define DECODE_ENABLE_SERIAL_PORT0
Definition: lpc.h:23
int lpc_set_wideio_range(uint16_t start, uint16_t size)
Program a LPC wide IO to support an IO range.
Definition: lpc_util.c:109
#define LPC_HOST_CONTROL
Definition: lpc.h:127
static void lpc_read_resources(struct device *dev)
Definition: lpc.c:99
static void configure_child_lpc_windows(struct device *dev, struct device *child)
Definition: lpc.c:146
static void lpc_enable_resources(struct device *dev)
Definition: lpc.c:309
static struct device_operations lpc_ops
Definition: lpc.c:322
static void lpc_set_resources(struct device *dev)
Definition: lpc.c:131
static void fch_ioapic_init(void)
Definition: lpc.c:39
static void configure_child_espi_windows(struct device *child)
Definition: lpc.c:278
static void setup_serirq(void)
Definition: lpc.c:25
static void lpc_init(struct device *dev)
Definition: lpc.c:45
static void lpc_enable_children_resources(struct device *dev)
Definition: lpc.c:290
static const unsigned short pci_device_ids[]
Definition: lpc.c:335
static const struct pci_driver lpc_driver __pci_driver
Definition: lpc.c:342
static const char * lpc_acpi_name(const struct device *dev)
Definition: lpc.c:310
static unsigned long southbridge_write_acpi_tables(const struct device *device, unsigned long start, struct acpi_rsdp *rsdp)
Definition: lpc.c:761
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
Definition: device.h:76
DEVTREE_CONST struct bus * next
Definition: device.h:80
DEVTREE_CONST struct device * children
Definition: device.h:79
void(* read_resources)(struct device *dev)
Definition: device.h:39
enum device_path_type type
Definition: path.h:114
Definition: device.h:107
DEVTREE_CONST struct device * sibling
Definition: device.h:111
struct device_path path
Definition: device.h:115
DEVTREE_CONST struct bus * link_list
Definition: device.h:139
DEVTREE_CONST struct resource * resource_list
Definition: device.h:134
unsigned int enabled
Definition: device.h:122
unsigned long flags
Definition: resource.h:49
resource_t base
Definition: resource.h:45
resource_t size
Definition: resource.h:46
DEVTREE_CONST struct resource * next
Definition: resource.h:48