coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
pci_ehci.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/pci_ehci.h>
5 #include <device/mmio.h>
6 #include <device/pci_ops.h>
7 #include <device/pci.h>
8 #include <device/pci_def.h>
9 #include <string.h>
10 
11 #include "ehci_debug.h"
12 #include "ehci.h"
13 
14 #if ENV_RAMSTAGE
15 static struct device_operations *ehci_drv_ops;
16 static struct device_operations ehci_dbg_ops;
17 #endif
18 
19 int ehci_debug_hw_enable(unsigned int *base, unsigned int *dbg_offset)
20 {
21  pci_devfn_t dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
22 
23  /* We only support controllers on bus 0. */
24  if (PCI_DEV2SEGBUS(dev) != 0)
25  return -1;
26 
27  u32 class = pci_s_read_config32(dev, PCI_CLASS_REVISION) >> 8;
28  if (class != PCI_EHCI_CLASSCODE)
29  return -1;
30 
31  u8 pm_cap = pci_s_find_capability(dev, PCI_CAP_ID_PM);
32  if (pm_cap) {
33  u16 pm_ctrl = pci_s_read_config16(dev, pm_cap + PCI_PM_CTRL);
34  /* Set to D0 and disable PM events. */
35  pm_ctrl &= ~PCI_PM_CTRL_PME_ENABLE;
36  pm_ctrl &= ~PCI_PM_CTRL_STATE_MASK;
37  pci_s_write_config16(dev, pm_cap + PCI_PM_CTRL, pm_ctrl);
38  }
39 
41  if (!pos)
42  return -1;
43 
44  u32 cap = pci_s_read_config32(dev, pos);
45 
46  /* FIXME: We should remove static EHCI_BAR_INDEX. */
47  u8 ehci_bar = 0x10 + 4 * ((cap >> 29) - 1);
48  if (ehci_bar != EHCI_BAR_INDEX)
49  return -1;
50 
51  pci_s_write_config32(dev, ehci_bar, CONFIG_EHCI_BAR);
52 
55 
56  *base = CONFIG_EHCI_BAR;
57  *dbg_offset = (cap>>16) & 0x1ffc;
58 
59  return 0;
60 }
61 
62 void ehci_debug_select_port(unsigned int port)
63 {
64  pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
65  pci_ehci_dbg_set_port(dbg_dev, port);
66 }
67 
68 #if ENV_RAMSTAGE
69 static void pci_ehci_set_resources(struct device *dev)
70 {
71  struct resource *res;
72 
73  printk(BIOS_DEBUG, "%s EHCI Debug Port hook triggered\n", dev_path(dev));
75 
76  if (ehci_drv_ops->set_resources)
77  ehci_drv_ops->set_resources(dev);
78  res = probe_resource(dev, EHCI_BAR_INDEX);
79  if (!res)
80  return;
81 
83  report_resource_stored(dev, res, "");
84  printk(BIOS_DEBUG, "%s EHCI Debug Port relocated\n", dev_path(dev));
85 }
86 
87 void pci_ehci_read_resources(struct device *dev)
88 {
89  pci_devfn_t dbg_dev = pci_ehci_dbg_dev(CONFIG_USBDEBUG_HCD_INDEX);
90 
91  if (!ehci_drv_ops && pci_match_simple_dev(dev, dbg_dev)) {
92  memcpy(&ehci_dbg_ops, dev->ops, sizeof(ehci_dbg_ops));
93  ehci_drv_ops = dev->ops;
94  ehci_dbg_ops.set_resources = pci_ehci_set_resources;
95  dev->ops = &ehci_dbg_ops;
96  printk(BIOS_DEBUG, "%s EHCI BAR hook registered\n", dev_path(dev));
97  } else {
98  printk(BIOS_DEBUG, "More than one caller of %s from %s\n", __func__, dev_path(dev));
99  }
100 
102 }
103 #endif
104 
106 {
107  u32 bar = pci_s_read_config32(sdev, EHCI_BAR_INDEX) & ~0x0f;
108  u8 *base = (u8 *)(uintptr_t)bar;
109  return base + HC_LENGTH(read32(base));
110 }
static uint32_t read32(const void *addr)
Definition: mmio.h:22
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
#define printk(level,...)
Definition: stdlib.h:16
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
void report_resource_stored(struct device *dev, const struct resource *resource, const char *comment)
Print the resource that was just stored.
Definition: device_util.c:508
const char * dev_path(const struct device *dev)
Definition: device_util.c:149
#define HC_LENGTH(p)
Definition: ehci.h:16
void usbdebug_disable(void)
void usbdebug_re_enable(uintptr_t ehci_base)
port
Definition: i915.h:29
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define PCI_CAP_ID_EHCI_DEBUG
Definition: pci_def.h:199
#define PCI_PM_CTRL_STATE_MASK
Definition: pci_def.h:234
#define PCI_PM_CTRL
Definition: pci_def.h:233
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_CAP_ID_PM
Definition: pci_def.h:191
#define PCI_COMMAND_MEMORY
Definition: pci_def.h:12
#define PCI_PM_CTRL_PME_ENABLE
Definition: pci_def.h:239
#define PCI_DEV2SEGBUS(sdev)
Definition: pci_def.h:554
#define PCI_COMMAND
Definition: pci_def.h:10
#define PCI_CLASS_REVISION
Definition: pci_def.h:40
unsigned int pci_match_simple_dev(struct device *dev, pci_devfn_t sdev)
Test for match between romstage and ramstage device instance.
Definition: pci_device.c:1293
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
int ehci_debug_hw_enable(unsigned int *base, unsigned int *dbg_offset)
Definition: pci_ehci.c:19
u8 * pci_ehci_base_regs(pci_devfn_t sdev)
Definition: pci_ehci.c:105
void ehci_debug_select_port(unsigned int port)
Definition: pci_ehci.c:62
#define EHCI_BAR_INDEX
Definition: pci_ehci.h:10
#define pci_ehci_read_resources
Definition: pci_ehci.h:22
pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx)
void pci_ehci_dbg_set_port(pci_devfn_t dev, unsigned int port)
#define PCI_EHCI_CLASSCODE
Definition: pci_ehci.h:11
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_config8(pci_devfn_t dev, uint16_t reg, uint8_t value)
Definition: pci_io_cfg.h:98
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
u16 pci_s_find_capability(pci_devfn_t dev, u16 cap)
Given a device, and a capability type, return the next matching capability.
Definition: pci_ops.c:72
u32 pci_devfn_t
Definition: pci_type.h:8
uintptr_t base
Definition: uart.c:17
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
void(* set_resources)(struct device *dev)
Definition: device.h:40
Definition: device.h:107
struct device_operations * ops
Definition: device.h:143
resource_t base
Definition: resource.h:45