thunderbolt: Limit USB3 bandwidth of certain Intel USB4 host routers
[ Upstream commit f0a57dd33b3eadf540912cd130db727ea824d174 ] Current Intel USB4 host routers have hardware limitation that the USB3 bandwidth cannot go higher than 16376 Mb/s. Work this around by adding a new quirk that limits the bandwidth for the affected host routers. Cc: stable@vger.kernel.org Signed-off-by: Gil Fine <gil.fine@linux.intel.com> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
3b29299e5f
commit
eddee1c229
@ -26,6 +26,19 @@ static void quirk_clx_disable(struct tb_switch *sw)
|
|||||||
tb_sw_dbg(sw, "disabling CL states\n");
|
tb_sw_dbg(sw, "disabling CL states\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw)
|
||||||
|
{
|
||||||
|
struct tb_port *port;
|
||||||
|
|
||||||
|
tb_switch_for_each_port(sw, port) {
|
||||||
|
if (!tb_port_is_usb3_down(port))
|
||||||
|
continue;
|
||||||
|
port->max_bw = 16376;
|
||||||
|
tb_port_dbg(port, "USB3 maximum bandwidth limited to %u Mb/s\n",
|
||||||
|
port->max_bw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct tb_quirk {
|
struct tb_quirk {
|
||||||
u16 hw_vendor_id;
|
u16 hw_vendor_id;
|
||||||
u16 hw_device_id;
|
u16 hw_device_id;
|
||||||
@ -43,6 +56,24 @@ static const struct tb_quirk tb_quirks[] = {
|
|||||||
* DP buffers.
|
* DP buffers.
|
||||||
*/
|
*/
|
||||||
{ 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation },
|
{ 0x8087, 0x0b26, 0x0000, 0x0000, quirk_dp_credit_allocation },
|
||||||
|
/*
|
||||||
|
* Limit the maximum USB3 bandwidth for the following Intel USB4
|
||||||
|
* host routers due to a hardware issue.
|
||||||
|
*/
|
||||||
|
{ 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI0, 0x0000, 0x0000,
|
||||||
|
quirk_usb3_maximum_bandwidth },
|
||||||
|
{ 0x8087, PCI_DEVICE_ID_INTEL_ADL_NHI1, 0x0000, 0x0000,
|
||||||
|
quirk_usb3_maximum_bandwidth },
|
||||||
|
{ 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI0, 0x0000, 0x0000,
|
||||||
|
quirk_usb3_maximum_bandwidth },
|
||||||
|
{ 0x8087, PCI_DEVICE_ID_INTEL_RPL_NHI1, 0x0000, 0x0000,
|
||||||
|
quirk_usb3_maximum_bandwidth },
|
||||||
|
{ 0x8087, PCI_DEVICE_ID_INTEL_MTL_M_NHI0, 0x0000, 0x0000,
|
||||||
|
quirk_usb3_maximum_bandwidth },
|
||||||
|
{ 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI0, 0x0000, 0x0000,
|
||||||
|
quirk_usb3_maximum_bandwidth },
|
||||||
|
{ 0x8087, PCI_DEVICE_ID_INTEL_MTL_P_NHI1, 0x0000, 0x0000,
|
||||||
|
quirk_usb3_maximum_bandwidth },
|
||||||
/*
|
/*
|
||||||
* CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
|
* CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
|
||||||
*/
|
*/
|
||||||
|
@ -252,6 +252,8 @@ struct tb_switch {
|
|||||||
* @ctl_credits: Buffers reserved for control path
|
* @ctl_credits: Buffers reserved for control path
|
||||||
* @dma_credits: Number of credits allocated for DMA tunneling for all
|
* @dma_credits: Number of credits allocated for DMA tunneling for all
|
||||||
* DMA paths through this port.
|
* DMA paths through this port.
|
||||||
|
* @max_bw: Maximum possible bandwidth through this adapter if set to
|
||||||
|
* non-zero.
|
||||||
*
|
*
|
||||||
* In USB4 terminology this structure represents an adapter (protocol or
|
* In USB4 terminology this structure represents an adapter (protocol or
|
||||||
* lane adapter).
|
* lane adapter).
|
||||||
@ -277,6 +279,7 @@ struct tb_port {
|
|||||||
unsigned int total_credits;
|
unsigned int total_credits;
|
||||||
unsigned int ctl_credits;
|
unsigned int ctl_credits;
|
||||||
unsigned int dma_credits;
|
unsigned int dma_credits;
|
||||||
|
unsigned int max_bw;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1865,6 +1865,15 @@ int usb4_port_retimer_nvm_read(struct tb_port *port, u8 index,
|
|||||||
usb4_port_retimer_nvm_read_block, &info);
|
usb4_port_retimer_nvm_read_block, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned int
|
||||||
|
usb4_usb3_port_max_bandwidth(const struct tb_port *port, unsigned int bw)
|
||||||
|
{
|
||||||
|
/* Take the possible bandwidth limitation into account */
|
||||||
|
if (port->max_bw)
|
||||||
|
return min(bw, port->max_bw);
|
||||||
|
return bw;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* usb4_usb3_port_max_link_rate() - Maximum support USB3 link rate
|
* usb4_usb3_port_max_link_rate() - Maximum support USB3 link rate
|
||||||
* @port: USB3 adapter port
|
* @port: USB3 adapter port
|
||||||
@ -1886,7 +1895,9 @@ int usb4_usb3_port_max_link_rate(struct tb_port *port)
|
|||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
lr = (val & ADP_USB3_CS_4_MSLR_MASK) >> ADP_USB3_CS_4_MSLR_SHIFT;
|
lr = (val & ADP_USB3_CS_4_MSLR_MASK) >> ADP_USB3_CS_4_MSLR_SHIFT;
|
||||||
return lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000;
|
ret = lr == ADP_USB3_CS_4_MSLR_20G ? 20000 : 10000;
|
||||||
|
|
||||||
|
return usb4_usb3_port_max_bandwidth(port, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1913,7 +1924,9 @@ int usb4_usb3_port_actual_link_rate(struct tb_port *port)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
lr = val & ADP_USB3_CS_4_ALR_MASK;
|
lr = val & ADP_USB3_CS_4_ALR_MASK;
|
||||||
return lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000;
|
ret = lr == ADP_USB3_CS_4_ALR_20G ? 20000 : 10000;
|
||||||
|
|
||||||
|
return usb4_usb3_port_max_bandwidth(port, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb4_usb3_port_cm_request(struct tb_port *port, bool request)
|
static int usb4_usb3_port_cm_request(struct tb_port *port, bool request)
|
||||||
|
Loading…
Reference in New Issue
Block a user