diff options
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/intel/jasperlake/chip.h | 5 | ||||
-rw-r--r-- | src/soc/intel/jasperlake/xhci.c | 43 |
2 files changed, 47 insertions, 1 deletions
diff --git a/src/soc/intel/jasperlake/chip.h b/src/soc/intel/jasperlake/chip.h index 36e9a1350b..4a9d9a0cf1 100644 --- a/src/soc/intel/jasperlake/chip.h +++ b/src/soc/intel/jasperlake/chip.h @@ -85,6 +85,11 @@ struct soc_intel_jasperlake_config { /* Wake Enable Bitmap for USB3 ports */ uint16_t usb3_wake_enable_bitmap; + /* Set the LFPS periodic sampling off time for USB3 Ports. + Default value of PMCTRL_REG bits[7:4] is 9 which means periodic + sampling off interval is 9ms, the range is from 0 to 15. */ + uint8_t xhci_lfps_sampling_offtime_ms; + /* SATA related */ uint8_t SataMode; uint8_t SataSalpSupport; diff --git a/src/soc/intel/jasperlake/xhci.c b/src/soc/intel/jasperlake/xhci.c index eebacca9eb..75663795d3 100644 --- a/src/soc/intel/jasperlake/xhci.c +++ b/src/soc/intel/jasperlake/xhci.c @@ -1,13 +1,20 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include <device/pci_type.h> +#include <console/console.h> +#include <device/mmio.h> #include <intelblocks/xhci.h> +#include <soc/soc_chip.h> #define XHCI_USB2_PORT_STATUS_REG 0x480 #define XHCI_USB3_PORT_STATUS_REG 0x500 #define XHCI_USB2_PORT_NUM 8 #define XHCI_USB3_PORT_NUM 6 +#define XHCI_PMCTRL 0x80A4 +/* BIT[7:4] LFPS periodic sampling off time for USB3 Ports */ +#define PMCTRL_LFPS_OFFTIME_SHIFT 4 +#define PMCTRL_LFPS_OFFTIME_MAX 0xF + static const struct xhci_usb_info usb_info = { .usb2_port_status_reg = XHCI_USB2_PORT_STATUS_REG, .num_usb2_ports = XHCI_USB2_PORT_NUM, @@ -20,3 +27,37 @@ const struct xhci_usb_info *soc_get_xhci_usb_info(pci_devfn_t xhci_dev) /* Jasper Lake only has one XHCI controller */ return &usb_info; } + +static void set_xhci_lfps_sampling_offtime(struct device *dev, uint8_t time_ms) +{ + void *addr; + const struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); + + if (!res) + return; + + if (time_ms > PMCTRL_LFPS_OFFTIME_MAX) { + printk(BIOS_ERR, + "XHCI: The maximum LFPS sampling OFF time is %u ms, " + "cannot set it to %u ms\n", + PMCTRL_LFPS_OFFTIME_MAX, time_ms); + + return; + } + + addr = (void *)(uintptr_t)(res->base + XHCI_PMCTRL); + clrsetbits32(addr, + PMCTRL_LFPS_OFFTIME_MAX << PMCTRL_LFPS_OFFTIME_SHIFT, + time_ms << PMCTRL_LFPS_OFFTIME_SHIFT); + printk(BIOS_DEBUG, + "XHCI: Updated LFPS sampling OFF time to %u ms\n", time_ms); +} + +void soc_xhci_init(struct device *dev) +{ + const config_t *config = config_of_soc(); + + /* Set xHCI LFPS period sampling off time */ + set_xhci_lfps_sampling_offtime(dev, + config->xhci_lfps_sampling_offtime_ms); +} |