diff options
author | Gil Fine <gil.fine@intel.com> | 2021-12-17 03:16:39 +0200 |
---|---|---|
committer | Mika Westerberg <mika.westerberg@linux.intel.com> | 2021-12-22 17:13:14 +0300 |
commit | 8a90e4fa3b4d6a10c96b0a04abf57bb5a16a8f4e (patch) | |
tree | 6c827d6d67aa7d5250f9d06dc59457493a5a1ca4 /drivers/thunderbolt/tb.h | |
parent | a28ec0e165ba2f90568828a2578aaa8540e13bc5 (diff) |
thunderbolt: Add CL0s support for USB4 routers
In this patch we add enabling of CL0s - a low power state of the link.
Low power states (called collectively CLx) are used to reduce
transmitter and receiver power when a high-speed lane is idle. For now,
we add support only for first low power state: CL0s. We enable it, if
both sides of the link support it, and only for the first hop router.
(i.e. the first device that connected to the host router). This is
needed for better thermal management.
Signed-off-by: Gil Fine <gil.fine@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Diffstat (limited to 'drivers/thunderbolt/tb.h')
-rw-r--r-- | drivers/thunderbolt/tb.h | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index b4487354e117..4ec89df69571 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -109,6 +109,13 @@ struct tb_switch_tmu { enum tb_switch_tmu_rate rate_request; }; +enum tb_clx { + TB_CLX_DISABLE, + TB_CL0S, + TB_CL1, + TB_CL2, +}; + /** * struct tb_switch - a thunderbolt switch * @dev: Device for the switch @@ -157,6 +164,7 @@ struct tb_switch_tmu { * @min_dp_main_credits: Router preferred minimum number of buffers for DP MAIN * @max_pcie_credits: Router preferred number of buffers for PCIe * @max_dma_credits: Router preferred number of buffers for DMA/P2P + * @clx: CLx state on the upstream link of the router * * When the switch is being added or removed to the domain (other * switches) you need to have domain lock held. @@ -205,6 +213,7 @@ struct tb_switch { unsigned int min_dp_main_credits; unsigned int max_pcie_credits; unsigned int max_dma_credits; + enum tb_clx clx; }; /** @@ -862,6 +871,20 @@ static inline bool tb_switch_is_titan_ridge(const struct tb_switch *sw) return false; } +static inline bool tb_switch_is_tiger_lake(const struct tb_switch *sw) +{ + if (sw->config.vendor_id == PCI_VENDOR_ID_INTEL) { + switch (sw->config.device_id) { + case PCI_DEVICE_ID_INTEL_TGL_NHI0: + case PCI_DEVICE_ID_INTEL_TGL_NHI1: + case PCI_DEVICE_ID_INTEL_TGL_H_NHI0: + case PCI_DEVICE_ID_INTEL_TGL_H_NHI1: + return true; + } + } + return false; +} + /** * tb_switch_is_usb4() - Is the switch USB4 compliant * @sw: Switch to check @@ -918,6 +941,33 @@ static inline bool tb_switch_tmu_hifi_is_enabled(const struct tb_switch *sw, sw->tmu.unidirectional == unidirectional; } +int tb_switch_enable_clx(struct tb_switch *sw, enum tb_clx clx); +int tb_switch_disable_clx(struct tb_switch *sw, enum tb_clx clx); + +/** + * tb_switch_is_clx_enabled() - Checks if the CLx is enabled + * @sw: Router to check the CLx state for + * + * Checks if the CLx is enabled on the router upstream link. + * Not applicable for a host router. + */ +static inline bool tb_switch_is_clx_enabled(const struct tb_switch *sw) +{ + return sw->clx != TB_CLX_DISABLE; +} + +/** + * tb_switch_is_cl0s_enabled() - Checks if the CL0s is enabled + * @sw: Router to check for the CL0s + * + * Checks if the CL0s is enabled on the router upstream link. + * Not applicable for a host router. + */ +static inline bool tb_switch_is_cl0s_enabled(const struct tb_switch *sw) +{ + return sw->clx == TB_CL0S; +} + int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged); int tb_port_add_nfc_credits(struct tb_port *port, int credits); int tb_port_clear_counter(struct tb_port *port, int counter); @@ -1097,6 +1147,7 @@ void usb4_port_unconfigure_xdomain(struct tb_port *port); int usb4_port_router_offline(struct tb_port *port); int usb4_port_router_online(struct tb_port *port); int usb4_port_enumerate_retimers(struct tb_port *port); +bool usb4_port_clx_supported(struct tb_port *port); int usb4_port_retimer_set_inbound_sbtx(struct tb_port *port, u8 index); int usb4_port_retimer_read(struct tb_port *port, u8 index, u8 reg, void *buf, |