blob: 49f919d78fb0fa7652716a129dc7a00b1557d0f0 [file] [log] [blame]
Karthikeyan Ramasubramanianaf0d5162020-11-04 17:05:35 -07001/* SPDX-License-Identifier: GPL-2.0-only */
2
Ben Kao6eb52532021-07-04 21:24:36 +08003#include <console/console.h>
4#include <device/mmio.h>
Karthikeyan Ramasubramanianaf0d5162020-11-04 17:05:35 -07005#include <intelblocks/xhci.h>
Ben Kao6eb52532021-07-04 21:24:36 +08006#include <soc/soc_chip.h>
Karthikeyan Ramasubramanianaf0d5162020-11-04 17:05:35 -07007
8#define XHCI_USB2_PORT_STATUS_REG 0x480
9#define XHCI_USB3_PORT_STATUS_REG 0x500
10#define XHCI_USB2_PORT_NUM 8
11#define XHCI_USB3_PORT_NUM 6
12
Ben Kao6eb52532021-07-04 21:24:36 +080013#define XHCI_PMCTRL 0x80A4
14/* BIT[7:4] LFPS periodic sampling off time for USB3 Ports */
15#define PMCTRL_LFPS_OFFTIME_SHIFT 4
16#define PMCTRL_LFPS_OFFTIME_MAX 0xF
17
Karthikeyan Ramasubramanianaf0d5162020-11-04 17:05:35 -070018static const struct xhci_usb_info usb_info = {
19 .usb2_port_status_reg = XHCI_USB2_PORT_STATUS_REG,
20 .num_usb2_ports = XHCI_USB2_PORT_NUM,
21 .usb3_port_status_reg = XHCI_USB3_PORT_STATUS_REG,
22 .num_usb3_ports = XHCI_USB3_PORT_NUM,
23};
24
Tim Wawrzynczak56fcfb52020-11-10 13:39:37 -070025const struct xhci_usb_info *soc_get_xhci_usb_info(pci_devfn_t xhci_dev)
Karthikeyan Ramasubramanianaf0d5162020-11-04 17:05:35 -070026{
Tim Wawrzynczak56fcfb52020-11-10 13:39:37 -070027 /* Jasper Lake only has one XHCI controller */
Karthikeyan Ramasubramanianaf0d5162020-11-04 17:05:35 -070028 return &usb_info;
29}
Ben Kao6eb52532021-07-04 21:24:36 +080030
31static void set_xhci_lfps_sampling_offtime(struct device *dev, uint8_t time_ms)
32{
33 void *addr;
Angel Ponsc1bfbe02021-11-03 13:18:53 +010034 const struct resource *res = probe_resource(dev, PCI_BASE_ADDRESS_0);
Ben Kao6eb52532021-07-04 21:24:36 +080035
36 if (!res)
37 return;
38
39 if (time_ms > PMCTRL_LFPS_OFFTIME_MAX) {
40 printk(BIOS_ERR,
41 "XHCI: The maximum LFPS sampling OFF time is %u ms, "
42 "cannot set it to %u ms\n",
43 PMCTRL_LFPS_OFFTIME_MAX, time_ms);
44
45 return;
46 }
47
48 addr = (void *)(uintptr_t)(res->base + XHCI_PMCTRL);
49 clrsetbits32(addr,
50 PMCTRL_LFPS_OFFTIME_MAX << PMCTRL_LFPS_OFFTIME_SHIFT,
51 time_ms << PMCTRL_LFPS_OFFTIME_SHIFT);
52 printk(BIOS_DEBUG,
53 "XHCI: Updated LFPS sampling OFF time to %u ms\n", time_ms);
54}
55
56void soc_xhci_init(struct device *dev)
57{
58 const config_t *config = config_of_soc();
59
60 /* Set xHCI LFPS period sampling off time */
61 set_xhci_lfps_sampling_offtime(dev,
62 config->xhci_lfps_sampling_offtime_ms);
63}