summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorGaggery Tsai <gaggery.tsai@intel.com>2018-12-28 10:26:44 -0800
committerDuncan Laurie <dlaurie@chromium.org>2019-01-11 23:42:39 +0000
commit3afb84a24583f5dee9fb407f11b32253d59392bf (patch)
treea1843c38806e7a4e938712c2fefea084bf25045e /src/drivers
parent64925b5128d8ed27bd1780f6cb25805aecc659e6 (diff)
downloadcoreboot-3afb84a24583f5dee9fb407f11b32253d59392bf.tar.xz
src/drivers/intel/wifi: Add a W/A for Intel ThP2 9260
This patch adds a workaround for ThP2. The PCIe root port LCTL2.TLS is by default GEN1 and ThP has bad synchronization on polarity inversion. When the root port request for speed change, ThP doesn’t confirm the request, and both sides are moving to polling after timeout, hot reset is issued, and then most of the CFG space is initialized. From the observation, CCC/ECPM/LTR would be reset to default but CCC/ECPM of root port and end devices have been reconfigured in pci_scan. The LTR configuration for root port is still missing. BUG=B:117618636 BRANCH=None TEST=Warm/cold reset for 10 times and didn't see unsupported request related AER error messages & $lspci -vvs 00:1c.0|grep LTR and ensure LTR+ is presenti & $iotools pci_read32 0 0x1c 0 0x68 and ensure bit10 is set. Change-Id: Id5d2814488fbc9db927edb2ead972b73ebc336ce Signed-off-by: Gaggery Tsai <gaggery.tsai@intel.com> Reviewed-on: https://review.coreboot.org/c/30486 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <siro@das-labor.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/intel/wifi/wifi.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/drivers/intel/wifi/wifi.c b/src/drivers/intel/wifi/wifi.c
index e19711425e..01a338d1d5 100644
--- a/src/drivers/intel/wifi/wifi.c
+++ b/src/drivers/intel/wifi/wifi.c
@@ -255,9 +255,34 @@ static const char *intel_wifi_acpi_name(const struct device *dev)
}
#endif
+static void pci_dev_apply_quirks(struct device *dev)
+{
+ unsigned int cap;
+ uint16_t val;
+ struct device *root = dev->bus->dev;
+
+ switch (dev->device) {
+ case PCI_DEVICE_ID_TP_9260_SERIES_WIFI:
+ cap = pci_find_capability(root, PCI_CAP_ID_PCIE);
+ /* Check the LTR for root port and enable it */
+ if (cap) {
+ val = pci_read_config16(root, cap +
+ PCI_EXP_DEV_CAP2_OFFSET);
+ if (val & LTR_MECHANISM_SUPPORT) {
+ val = pci_read_config16(root, cap +
+ PCI_EXP_DEV_CTL_STS2_CAP_OFFSET);
+ val |= LTR_MECHANISM_EN;
+ pci_write_config16(root, cap +
+ PCI_EXP_DEV_CTL_STS2_CAP_OFFSET, val);
+ }
+ }
+ }
+}
+
static void wifi_pci_dev_init(struct device *dev)
{
pci_dev_init(dev);
+ pci_dev_apply_quirks(dev);
if (IS_ENABLED(CONFIG_ELOG)) {
uint32_t val;