summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/jasperlake/chip.h5
-rw-r--r--src/soc/intel/jasperlake/xhci.c43
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);
+}