Commit 6faa39ee authored by Mika Westerberg's avatar Mika Westerberg

thunderbolt: Skip discovery also in USB4 v2 host

If the host router is reset, there is no point running discovery as the
links are down. Furthermore this prevents CL-state enabling. For this
reason skip discovery in USB4 v2 host the same way we do with USB4 v1.
Reviewed-by: default avatarMario Limonciello <mario.limonciello@amd.com>
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
parent 8cf9926c
...@@ -1221,7 +1221,7 @@ static void nhi_check_iommu(struct tb_nhi *nhi) ...@@ -1221,7 +1221,7 @@ static void nhi_check_iommu(struct tb_nhi *nhi)
str_enabled_disabled(port_ok)); str_enabled_disabled(port_ok));
} }
static bool nhi_reset(struct tb_nhi *nhi) static void nhi_reset(struct tb_nhi *nhi)
{ {
ktime_t timeout; ktime_t timeout;
u32 val; u32 val;
...@@ -1229,11 +1229,11 @@ static bool nhi_reset(struct tb_nhi *nhi) ...@@ -1229,11 +1229,11 @@ static bool nhi_reset(struct tb_nhi *nhi)
val = ioread32(nhi->iobase + REG_CAPS); val = ioread32(nhi->iobase + REG_CAPS);
/* Reset only v2 and later routers */ /* Reset only v2 and later routers */
if (FIELD_GET(REG_CAPS_VERSION_MASK, val) < REG_CAPS_VERSION_2) if (FIELD_GET(REG_CAPS_VERSION_MASK, val) < REG_CAPS_VERSION_2)
return false; return;
if (!host_reset) { if (!host_reset) {
dev_dbg(&nhi->pdev->dev, "skipping host router reset\n"); dev_dbg(&nhi->pdev->dev, "skipping host router reset\n");
return false; return;
} }
iowrite32(REG_RESET_HRR, nhi->iobase + REG_RESET); iowrite32(REG_RESET_HRR, nhi->iobase + REG_RESET);
...@@ -1244,14 +1244,12 @@ static bool nhi_reset(struct tb_nhi *nhi) ...@@ -1244,14 +1244,12 @@ static bool nhi_reset(struct tb_nhi *nhi)
val = ioread32(nhi->iobase + REG_RESET); val = ioread32(nhi->iobase + REG_RESET);
if (!(val & REG_RESET_HRR)) { if (!(val & REG_RESET_HRR)) {
dev_warn(&nhi->pdev->dev, "host router reset successful\n"); dev_warn(&nhi->pdev->dev, "host router reset successful\n");
return true; return;
} }
usleep_range(10, 20); usleep_range(10, 20);
} while (ktime_before(ktime_get(), timeout)); } while (ktime_before(ktime_get(), timeout));
dev_warn(&nhi->pdev->dev, "timeout resetting host router\n"); dev_warn(&nhi->pdev->dev, "timeout resetting host router\n");
return false;
} }
static int nhi_init_msi(struct tb_nhi *nhi) static int nhi_init_msi(struct tb_nhi *nhi)
...@@ -1333,7 +1331,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1333,7 +1331,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct tb_nhi *nhi; struct tb_nhi *nhi;
struct tb *tb; struct tb *tb;
bool reset;
int res; int res;
if (!nhi_imr_valid(pdev)) if (!nhi_imr_valid(pdev))
...@@ -1367,12 +1364,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1367,12 +1364,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
nhi_check_quirks(nhi); nhi_check_quirks(nhi);
nhi_check_iommu(nhi); nhi_check_iommu(nhi);
nhi_reset(nhi);
/*
* Only USB4 v2 hosts support host reset so if we already did
* that then don't do it again when the domain is initialized.
*/
reset = nhi_reset(nhi) ? false : host_reset;
res = nhi_init_msi(nhi); res = nhi_init_msi(nhi);
if (res) if (res)
...@@ -1399,7 +1391,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1399,7 +1391,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev_dbg(dev, "NHI initialized, starting thunderbolt\n"); dev_dbg(dev, "NHI initialized, starting thunderbolt\n");
res = tb_domain_add(tb, reset); res = tb_domain_add(tb, host_reset);
if (res) { if (res) {
/* /*
* At this point the RX/TX rings might already have been * At this point the RX/TX rings might already have been
......
...@@ -2584,6 +2584,7 @@ static int tb_scan_finalize_switch(struct device *dev, void *data) ...@@ -2584,6 +2584,7 @@ static int tb_scan_finalize_switch(struct device *dev, void *data)
static int tb_start(struct tb *tb, bool reset) static int tb_start(struct tb *tb, bool reset)
{ {
struct tb_cm *tcm = tb_priv(tb); struct tb_cm *tcm = tb_priv(tb);
bool discover = true;
int ret; int ret;
tb->root_switch = tb_switch_alloc(tb, &tb->dev, 0); tb->root_switch = tb_switch_alloc(tb, &tb->dev, 0);
...@@ -2629,9 +2630,13 @@ static int tb_start(struct tb *tb, bool reset) ...@@ -2629,9 +2630,13 @@ static int tb_start(struct tb *tb, bool reset)
* reset the ports to handle it as new hotplug for USB4 v1 * reset the ports to handle it as new hotplug for USB4 v1
* routers (for USB4 v2 and beyond we already do host reset). * routers (for USB4 v2 and beyond we already do host reset).
*/ */
if (reset && usb4_switch_version(tb->root_switch) == 1) { if (reset && tb_switch_is_usb4(tb->root_switch)) {
discover = false;
if (usb4_switch_version(tb->root_switch) == 1)
tb_switch_reset(tb->root_switch); tb_switch_reset(tb->root_switch);
} else { }
if (discover) {
/* Full scan to discover devices added before the driver was loaded. */ /* Full scan to discover devices added before the driver was loaded. */
tb_scan_switch(tb->root_switch); tb_scan_switch(tb->root_switch);
/* Find out tunnels created by the boot firmware */ /* Find out tunnels created by the boot firmware */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment