From 7c37bb304fd6c085f9630d1740ed53781d4d4821 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 23 Mar 2021 19:05:23 +0200 Subject: [PATCH] thunderbolt: Add quirk for Intel Goshen Ridge DP credits Intel Goshen Ridge reports wrong DP main credits in NVM 27 and earlier, so add a quirk that fixes it. We also need to expand the quirk table to match on hardware vendor/device IDs too. Signed-off-by: Mika Westerberg --- drivers/thunderbolt/quirks.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/thunderbolt/quirks.c b/drivers/thunderbolt/quirks.c index 892cf0e8ada5..b5f2ec79c4d6 100644 --- a/drivers/thunderbolt/quirks.c +++ b/drivers/thunderbolt/quirks.c @@ -12,7 +12,17 @@ static void quirk_force_power_link(struct tb_switch *sw) sw->quirks |= QUIRK_FORCE_POWER_LINK_CONTROLLER; } +static void quirk_dp_credit_allocation(struct tb_switch *sw) +{ + if (sw->credit_allocation && sw->min_dp_main_credits == 56) { + sw->min_dp_main_credits = 18; + tb_sw_dbg(sw, "quirked DP main: %u\n", sw->min_dp_main_credits); + } +} + struct tb_quirk { + u16 hw_vendor_id; + u16 hw_device_id; u16 vendor; u16 device; void (*hook)(struct tb_switch *sw); @@ -20,8 +30,13 @@ struct tb_quirk { static const struct tb_quirk tb_quirks[] = { /* Dell WD19TB supports self-authentication on unplug */ - { 0x00d4, 0xb070, quirk_force_power_link }, - { 0x00d4, 0xb071, quirk_force_power_link }, + { 0x0000, 0x0000, 0x00d4, 0xb070, quirk_force_power_link }, + { 0x0000, 0x0000, 0x00d4, 0xb071, quirk_force_power_link }, + /* + * Intel Goshen Ridge NVM 27 and before report wrong number of + * DP buffers. + */ + { 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation }, }; /** @@ -37,7 +52,15 @@ void tb_check_quirks(struct tb_switch *sw) for (i = 0; i < ARRAY_SIZE(tb_quirks); i++) { const struct tb_quirk *q = &tb_quirks[i]; - if (sw->device == q->device && sw->vendor == q->vendor) - q->hook(sw); + if (q->hw_vendor_id && q->hw_vendor_id != sw->config.vendor_id) + continue; + if (q->hw_device_id && q->hw_device_id != sw->config.device_id) + continue; + if (q->vendor && q->vendor != sw->vendor) + continue; + if (q->device && q->device != sw->device) + continue; + + q->hook(sw); } }